0

A json stream described an array of shapes. The shapes mayb be triangles, rectangles or squares.

For example:

{"shapes": [
    {"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
    {"type": "rectangle", "width": 4, "height": 3},
    {"type": "square", "side": 3}
]}

These structures are declared in my golang code:

type Shape struct {
    Type string `json:"type"`
}

type Triangle struct {
    Shape
    Side1 int `json:"side1"`
    Side2 int `json:"side2"`
    Side3 int `json:"side3"`
}

type Rectangle struct {
    Shape
    Width  int `json:"width"`
    Height int `json:"height"`
}

type Square struct {
    Shape
    Side int `json:"side"`
}

How can I decode the json into an object slice? Thank you very much.

1 Answer 1

1

Create new type Shapesto unmarshal shapes and implement your custom UnmarshalJSON to Shapes

type Shapes struct {
    Shapes []interface{} `json:"shapes"`
}

func (b *Shapes) UnmarshalJSON(data []byte) error {

    var v = struct {
        Shapes []map[string]interface{} `json:"shapes"`
    }{}
    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }
    types := make([]interface{}, 0)

    for _, shape := range v.Shapes {
        shp := Shape{Type: shape[`type`].(string)}
        switch shp.Typ() {
        case `triangle`:
            typ := Triangle{
                Shape:shp,
                Side1: int(shape[`side1`].(float64)),
                Side2: int(shape[`side2`].(float64)),
                Side3: int(shape[`side3`].(float64)),
            }
            types = append(types, typ)
        case `rectangle`:
            typ := Rectangle{
                Shape:  shp,
                Width:  int(shape[`width`].(float64)),
                Height: int(shape[`height`].(float64)),
            }
            types = append(types, typ)
        case `square`:
            typ := Square{
                Shape:  shp,
                Side:  int(shape[`side`].(float64)),
            }
            types = append(types, typ)
        }
    }

    b.Shapes = types

    return nil
}

Unmarshal json string to Shapes type. You can access your shape types in Shapes.Shapes array.

func main() {
    jStr := `{"shapes": [
    {"type": "triangle", "side1": 3, "side2": 4, "side3": 5},
    {"type": "rectangle", "width": 4, "height": 3},
    {"type": "square", "side": 3}
]}`

    shapes := Shapes{}
    err := json.Unmarshal([]byte(jStr), &shapes)
    if err != nil {
        panic(err)
    }
    fmt.Println(shapes)
}

Find full code here

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

1 Comment

Got it. Thank you very much~

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.