2

I'm trying to parse this type of response from a server:

[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]

Besides writing my own hack'ish parser for this type of messages is there a standard way to interpret this that I'm not aware of?

1 Answer 1

7

Your input is a JSON string. In Go, you can use the encoding/json package to decode it.

Usually, when the structure of the JSON string is known prior, a Go struct type can be constructed which models it, and then you can unmarshal into a value of that struct type.

If the structure is unknown or is varying, you may unmarshal into a value of type interface{} which can be the target of any JSON data:

s := `[[1,"a","b",2,"000000",[[1,2,3],[1,2,3]],"x","y","z",[[1,2,3],[1,2,3]]]]`

var v interface{}
if err := json.Unmarshal([]byte(s), &v); err != nil {
    fmt.Println(err)
    return
}
fmt.Println(v)
fmt.Printf("%#v\n", v)

Output (try it on the Go Playground):

[[1 a b 2 000000 [[1 2 3] [1 2 3]] x y z [[1 2 3] [1 2 3]]]]
[]interface {}{[]interface {}{1, "a", "b", 2, "000000", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}, "x", "y", "z", []interface {}{[]interface {}{1, 2, 3}, []interface {}{1, 2, 3}}}}

As you can see, the result is a slice of slices, with elements of varying types (JSON numbers, strings and even more slices).

Here's the same output adding indentation to get a better feeling of it (using Go's composite literal syntax):

[]interface{}{
    []interface{}{
        1, "a", "b", 2, "000000",
        []interface{}{
            []interface{}{1, 2, 3},
            []interface{}{1, 2, 3}},
        "x", "y", "z",
        []interface{}{
            []interface{}{1, 2, 3},
            []interface{}{1, 2, 3},
        },
    },
}

Of course this is not very convenient, as you have to use type assertion to "extract" values from this "generic" value of type interface{}, for example to extract the first 2 non-arrays values (also printing their types for verification):

fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[0])
fmt.Printf("%T %[1]v\n", v.([]interface{})[0].([]interface{})[1])

Output:

float64 1
string a

Worth noting that JSON numbers in Go are unmarshaled to a value of type float64 even though they could be integers (unless another type is explicitly specified).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.