This question already has an answer here:
Assume I have this data:
{
"code": 10000,
"msg": "Successful request processing",
"asks": [
[
"0.03434400",
"0.31100000"
],
[
"0.03436300",
"0.18900000"
],
[
],
"bids": [
[
"0.03427400",
"0.21100000"
],...
Thanks to the Go to JSON converter, I know it can be parsed like this (working, in my script):
type AutoGenerated struct {
Code int `json:"code"`
Msg string `json:"msg"`
Asks [][]string `json:"asks"`
Bids [][]string `json:"bids"`
}
I'd rather parse it like this:
type Box struct {
Number int `json:"code"`
Message string `json:"msg"`
Asks []MarketData `json:"asks"`
Bids []MarketData `json:"bids"`
}
type MarketData struct {
Sell []string
}
Or, even better, this (assuming Box struct stays the same):
type MarketData struct {
SellPrice string
SellQuantity string
}
The problem is that if I try to print the above using price :=response.Asks[0].SellPrice, or using the previous example, response.Asks[0].Sell, I get an empty struct.
Why doesn't this work? It seems like legitimate go, to me. It builds fine, but whenever I try to run it, it prints empty braces.
</div>
You are changing the structure of the data, of course it will not parse the same way.
You can probably do it like this:
type MarketDataInput []string
This doesn't give you useful field names.
If you can't change the structure of the input data, you can probably do this instead:
func (m MarketData) SellPrice() string {
return m[0]
}
func (m MarketData) SellQuantity() string {
return m[1]
}
But overall this just seems like a bad way of handling the data. You should probably transform it to a different data structure after you parse it to json.
type MarketDataInput []string
type MarketData struct {
SellPrice float64
SellQuantity float64
}
func MarketDataFromInputs(inputs []MarketDataInput) []MarketData {
var output = make([]MarketData, 0, len(inputs))
for _, input := range inputs {
var item MarketData
item.SellPrice, _ = strconv.ParseFloat(input[0], 64)
item.SellQuantity, _ = strconv.ParseFloat(input[1], 64)
output = append(output, item)
}
return output
}
Now you have the data in a more useful structure that you can process better.
package main
import (
"encoding/json"
"fmt"
)
var j = `{
"code": 10000,
"msg": "Successful request processing",
"asks": [
[
"0.03434400",
"0.31100000"
],
[
"0.03436300",
"0.18900000"
]
],
"bids": [
[
"0.03427400",
"0.21100000"
]
]
}
`
type Box struct {
Number int `json:"code"`
Message string `json:"msg"`
Asks []MarketData `json:"asks"`
Bids []MarketData `json:"bids"`
}
type MarketData struct {
SellPrice string
SellQuantity string
}
func (md *MarketData) UnmarshalJSON(d []byte) error {
val := []string{}
err := json.Unmarshal(d, &val)
if err != nil {
return err
}
if len(val) != 2 {
return fmt.Errorf("MarketData unmarshal error len != 2")
}
md.SellPrice = val[0]
md.SellQuantity = val[1]
return nil
}
func main() {
ins := new(Box)
err := json.Unmarshal([]byte(j), ins)
if err != nil {
panic(err)
}
fmt.Printf("%+v
", ins)
}