0

I apologise in advance if this question is considered too easy or whatever; this is the first time I'm writing anything in go. I have two structs (simplified for this question)

type A struct {
    Content string
}

type B struct {
    Element A `json:"0"`
    Children []B `json:"1"`
}

I want to encode a value of type B into JSON, but instead of returning an object it should return a json array

For example:

What I get:

[
    {
        "0":{
            "Content":"AAA"
        },
        "1":[
            {
                "0":{
                    "Content":"BBB"
                },
                "1":[
                    {
                        "0":{
                            "Content":"CCC"
                        },
                        "1":[]
                    },
                    {
                        "0":{
                            "Content":"DDD"
                        },
                        "1":[]
                    }
                }
            ]
        ]
    }
]

What I need:

[
    {"Content": "AAA"}, 
    [
        [
            {"Content": "BBB"},
            [
                {"Content": "CCC"}, 
                []
            ]
        ], 
        [
            {"Content": "DDD"}, 
            []
        ]
    ]
]

I could do this by manually iterating through it, but I would hope that there's an integrated way to do it

2
  • Please format your JSON strings usign line breaks & indent. It's not readable at the moment and hard to understand the difference. Commented Nov 1, 2017 at 16:12
  • 1
    There isn't. A Go struct equates to a JSON object, not a JSON array. You could do it yourself with a custom UnmarshalJSON. Commented Nov 1, 2017 at 16:13

2 Answers 2

1

You may do so by implementing json.Marshaler interface in B.

For example: https://play.golang.org/p/fT1WlQ5Raz

package main

import (
    "encoding/json"
    "fmt"
)

type A struct {
    Content string
}

type B struct {
    Element  A
    Children []B
}

// MarshalJSON implements json.Marshaler
func (b B) MarshalJSON() ([]byte, error) {
    return json.Marshal([]interface{}{
        b.Element,
        b.Children,
    })
}

func main() {

    root := B{
        Element: A{Content: "AAA"},
        Children: []B{
            B{
                Element: A{Content: "BBB"},
                Children: []B{
                    B{Element: A{Content: "CCC"}, Children: []B{}},
                    B{Element: A{Content: "DDD"}, Children: []B{}},
                },
            },
        },
    }

    content, _ := json.MarshalIndent(root, "", "  ")
    fmt.Printf("%s\n", content)
}

Results:

[
  {
    "Content": "AAA"
  },
  [
    [
      {
        "Content": "BBB"
      },
      [
        [
          {
            "Content": "CCC"
          },
          []
        ],
        [
          {
            "Content": "DDD"
          },
          []
        ]
      ]
    ]
  ]
]
Sign up to request clarification or add additional context in comments.

Comments

0

i think you need a slice of interface to wrap both A and B struct into a single slice

please take a look at my snippet here https://play.golang.org/p/c0xldskKyz

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.