0

With json objects it's simple:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   []string `json:"prop2"`
}

How would I cast simple []string slice against MyObj? I know I could iterate over slice and manually assign each property by respective index, but maybe there's more optimal way, considering that Prop1 references at 0 index of the slice, and Prop2 - 1.

EDIT1:

My actual JSON string looks like [100, 200]. So MyObj.Prop1 would get filled with 100, and MyObj.Prop2 with 200 respectively.

Thank you.

5
  • Do you mean you want to cast a []MyObj into a []string? Commented May 12, 2017 at 8:17
  • Could you also show us how your string would look like? Commented May 12, 2017 at 8:20
  • Other way around. I have JSON [100, 200] and I want to cast it into MyObj, so that I could access 100 with MyObj.Prop1 and 200 with MyObj.Prop2. Commented May 12, 2017 at 8:21
  • 1
    According to the MyObj you defined, your json should look like this: {"prop1":100,"prop2":["200"]}. Since prop1 is an int, and prop2 is a []string Commented May 12, 2017 at 8:27
  • I know how to deal with that kind of JSON, but there's a portion of it which stays as [100, 200]. Commented May 12, 2017 at 8:29

2 Answers 2

3

You'll need a custom json.Umnarshaller:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   int      `json:"prop2"`
}

func (a *MyObj) UnmarshalJSON(b []byte) error {
    s := []string{}

    if err := json.Unmarshal(b, &s); err != nil {
        return err
    }

    l := len(s)

    // Check slice bounds and errors!!
    a.Prop1, _ = strconv.Atoi(s[0])
    a.Prop2, _ = strconv.Atoi(s[l-1])

    return nil
}

Example: https://play.golang.org/p/fVobgtrqNw

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

2 Comments

Thanks. I see we still have to manually assign Prop1 and Prop2. I was wondering if we had an automated way of doing something like MyObj[0] = slice[0] meaning that Prop1 resides at index 0 within MyObj.
MyObj[0] and slice[0] are different types (type MyObj and string respectively). The = operation you want can not be done. Your best bet is to write a custom unmarshaler with the required behavior once so you can avoid manual assignment every time a json data presents itself.
2

Given that you have your json as a string in a variable (yourString) then you can Unmarshall that into your []MyObj

yourString := `{"prop1":"100","prop2":"200"}`
var myObj MyObj
err := json.Unmarshal([]byte(yourString), &myObj)
if err == nil {
    fmt.Printf("%+v\n", myObj)
} else {
    fmt.Println(err)
    fmt.Printf("%+v\n", myObj)
}

Alternatively you can do this using json.decode:

yourString := `{"a" : ["prop1":100,"prop2":["200"]}`
var myObj MyObj
err := json.NewDecoder(strings.NewReader(yourString)).Decode(&myObj)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println(myObj.Prop1)
fmt.Println(myObj.Prop2)

Update

According to the MyObj you defined, your json should look like this: {"prop1":100,"prop2":["200"]}. Since prop1 is an int, and prop2 is a []string I think you either need to change your struct or change your json.

For instance you could define your MyObj like this:

type MyObj struct {
    Prop1   int      `json:"prop1"`
    Prop2   string   `json:"prop2"`
}

To match a json object like this:

{"prop1":100,"prop2":"200"}

If you want to keep MyObj as it is then your json should look like this:

{"prop1":100,"prop2":["200"]}

Check in the go playground: https://play.golang.org/p/yMpeBbjhkt

2 Comments

Thank you. However I explicitly said that I need to cast []string into MyObj struct. I know how to do it with [string]string
@AleksandrMakov then I believe that the example I provided in the go playground should work.

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.