2017-06-05 206 views
1

發現去json解碼是一個很大的痛苦,所以請幫助。 這裏是我的JSON:去解碼json字符串

{ 
    "BTC_BCN":{ 
     "id":7, 
     "last":"0.00000156", 
     "lowestAsk":"0.00000156", 
     "highestBid":"0.00000155", 
     "percentChange":"0.01960784", 
     "baseVolume":"4920.84786257", 
     "quoteVolume":"3016048494.19305944", 
     "isFrozen":"0", 
     "high24hr":"0.00000183", 
     "low24hr":"0.00000145" 
    }, 
    "BTC_BELA":{ 
     "id":8, 
     "last":"0.00008847", 
     "lowestAsk":"0.00008848", 
     "highestBid":"0.00008847", 
     "percentChange":"-0.00405268", 
     "baseVolume":"169.66498061", 
     "quoteVolume":"1981232.44495809", 
     "isFrozen":"0", 
     "high24hr":"0.00008995", 
     "low24hr":"0.00008120" 
    }, ... 
} 

所以我需要把在我創建

//Crypto is the currency object 
type Crypto struct { 
    iso   string //this is the key (ex: BTC_BCN) 
    id   int 
    last   float64 
    lowestAsk  float64 
    highestBid float64 
    percentChange float64 
    baseVolume float64 
    quoteVolume float64 
    isFrozen  int 
    high24hr  float64 
    low24hr  float64 
} 

這裏一類是我做過什麼,到目前爲止,但我結束了鍵到位,一個空值

func main() { 
    // sendEmail("Some text") 
    currencies := getCurrencies() 
    if currencies == nil { 
     return 
    } 
    fmt.Println(len(currencies)) 

} 

func getCurrencies() map[string]Crypto { 
    curList := make(map[string]Crypto) 
    resp, err := http.Get("https://poloniex.com/public?command=returnTicker") 
    // fmt.Println(err) 
    if err != nil { 
     sendEmail("Error getting data from poloniex " + err.Error()) 
     return nil 
    } 
    body, readErr := ioutil.ReadAll(resp.Body) 
    reader := strings.NewReader(string(body)) 
    jsonErr := json.NewDecoder(reader).Decode(&curList) 
    // fmt.Printf("curList is : %#v\n", curList) 
    // fmt.Printf("body is : %s\n", string(body)) 
    if readErr != nil { 
     fmt.Printf("readErr: %s\n", readErr.Error()) 
    } 
    if jsonErr != nil { 
     fmt.Printf("jsonErr: %s\n", jsonErr.Error()) 
    } 
    for k, v := range curList { 
     fmt.Println("k:", k, "v:", v) 
    } 
    defer resp.Body.Close() 
    return curList 
} 

輸出:

k: BTC_MAID v: {0 0 0 0 0 0 0 0 0 0} 
k: BTC_NOTE v: {0 0 0 0 0 0 0 0 0 0} 
k: BTC_VRC v: {0 0 0 0 0 0 0 0 0 0} 
k: BTC_DOGE v: {0 0 0 0 0 0 0 0 0 0}... 

請原諒我的愚蠢問題,但我花了幾天的時間,我想我錯過了一些東西。 乾杯。

回答

2
//Crypto is the currency object 
type Crypto struct { 
    Iso   string //this is the key (ex: BTC_BCN) 
    Id   int 
    Last   string 
    LowestAsk  string 
    HighestBid string 
    PercentChange string 
    BaseVolume string 
    QuoteVolume string 
    IsFrozen  int 
    High24hr  string 
    Low24hr  string 
} 

你需要通過資本第一個字符導出的字段。最重要的是,您的float64數據類型爲:string,因此您可以在將其分配給對象Crypto之前以字符串或格式讀取。


更新時間:

正如指出的@skomp,您可以使用標籤來標註你從JSON文件接收的類型。

type Crypto struct { 
    CryptoKey 
    Id   int 
    Last   float64 `json:"last,string"` 
    LowestAsk  float64 `json:"lowestAsk,string"` 
    HighestBid float64 `json:"highestBid,string"` 
    PercentChange float64 `json:"percentChange,string"` 
    BaseVolume float64 `json:"baseVolume,string"` 
    QuoteVolume float64 `json:"quoteVolume,string"` 
    IsFrozen  int 
    High24hr  float64 `json:"high24hr,string"` 
    Low24hr  float64 `json:"low24hr,string"` 
} 
+0

謝謝,夥計!工作。 –

+1

關於字符串中的浮點數:標記可以幫助:'{... Last float64 \'json:「last,string」\'...'},這也允許您將名稱與名稱分開在結構中。 – skomp

1

您正試圖解碼包含您的加密對象的地圖。這是不正確的。創建結構定義的映射,像這樣:

type Crypto struct { 
    iso   string `json:"BTC_BCN"` //this is the key (ex: BTC_BCN) 
    id   int  `json:"id"` 
    last   float64 `json:"las"` 
    ... 
} 

crypto := &Crypto{} 
err = json.NewDecoder(reader).Decode(crypto) 
+0

問題是與'ISO'它是動態的,我從API調用得到,我永遠不知道我會得到什麼新的isos。 –

+0

這沒有任何意義 - BTC_BCN是*包含此結構*的字段的名稱,而不是此結構*中字段*的名稱。 – Adrian