1

I am processing data from a text file with go and would like to ouput a json record like this:

[{
        "ship": "RMS Titanic",
        "crew": [{
            "name": "Captain Smith"
        }, {
            "name": "First Officer Murdoch"
        }],
        "passengers": [{
            "name": "Jack Dawson"
        }, {
            "name": "Rose Dewitt Bukater"
        }]
    },
    {
        "ship": "ship2",
        "crew": [{
            "name": "crew 1"
        }, {
            "name": "crew 2"
        }],
        "passengers": [{
            "name": "passenger 1"
        }, {
            "name": "passenger 2"
        }]
    }
]

Here is a snippet from my code:

package main

import (
        "fmt"
        "encoding/json"
)

func main() {
        var crew []map[string]string
        var passengers []map[string]string

        s1 := map[string]string{ "name": "RMS Titanic"}
        j1, _ := json.Marshal(s1)
        fmt.Printf("j1: %s\n", string(j1))

        s2 := map[string]string{ "name": "Captain Smith" }
        crew = append(crew, s2)
        s2 = map[string]string{ "name": "First Officer Murdoch" }
        crew = append(crew, s2)
        j2, _ := json.Marshal(crew)
        fmt.Printf("j2: %s\n", string(j2))

        s3 := map[string]string{ "name": "Jack Dawson"}
        passengers = append(passengers, s3)
        s3 = map[string]string{ "name": "Rose Dewitt Bukater" }
        passengers = append(passengers, s3)

        j3, _ := json.Marshal(passengers)
        fmt.Printf("j3: %s\n", string(j3))

        s4 :=  map[string]string{"crew": string(j2), "passengers": string(j3)}
        j4, _ := json.Marshal(s4)
        fmt.Printf("j4: %s\n", string(j4))

}

Output:

j1: {"name":"RMS Titanic"}
j2: [{"name":"Captain Smith"},{"name":"First Officer Murdoch"}]
j3: [{"name":"Jack Dawson"},{"name":"Rose Dewitt Bukater"}]
j4: {"crew":"[{\"name\":\"Captain Smith\"},{\"name\":\"First Officer Murdoch\"}]","passengers":"[{\"name\":\"Jack Dawson\"},{\"name\":\"Rose Dewitt Bukater\"}]"}

I am processing the ship data in j1, the crew data in j2 and the passengers data in j3.

I have managed to merge j2 and j3 together into j4, but the quotation mark s are escapaded, how un-escape the quotation marks ?

How to insert j1 data in there so the output match the json output I wish for ?

1
  • This 3rd party lib might be of great help to you: github.com/icza/dyno (disclosure: I'm the author). Commented Mar 18, 2018 at 13:32

1 Answer 1

1

The solution is not to unescape the string, but to marshal the complete structure you want to serialize to JSON, for example:

ship1 := map[string]interface{}{
    "ship": "RMS Titanic",
    "crew": crew,
    "passengers": passengers,
}

ship1Json, err := json.Marshal(ship1)
if err != nil {
    panic(err)
}

fmt.Println("ship1:", string(ship1Json))

Another example with two ships in a slice:

ship2 := map[string]interface{}{
    "ship": "ship2",
    "crew": crew,
    "passengers": passengers,
}

ships := []map[string]interface{}{ship1, ship2}

shipsJson, err := json.Marshal(ships)
if err != nil {
    panic(err)
}

fmt.Println("ships:", string(shipsJson))

The result is easier to see if we print the JSON indented:

indented, err := json.MarshalIndent(ships, "", "  ")
if err != nil {
    panic(err)
}

fmt.Println(string(indented))

Giving:

[
  {
    "crew": [
      {
        "name": "Captain Smith"
      },
      {
        "name": "First Officer Murdoch"
      }
    ],
    "passengers": [
      {
        "name": "Jack Dawson"
      },
      {
        "name": "Rose Dewitt Bukater"
      }
    ],
    "ship": "RMS Titanic"
  },
  {
    "crew": [
      {
        "name": "Captain Smith"
      },
      {
        "name": "First Officer Murdoch"
      }
    ],
    "passengers": [
      {
        "name": "Jack Dawson"
      },
      {
        "name": "Rose Dewitt Bukater"
      }
    ],
    "ship": "ship2"
  }
]

See also on the playground.

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

2 Comments

Thank you, very good ! Is there a way to insert s1 directly in ship1 ? I tried ship1 := map[string]interface{}{ s1, "crew": crew,"passengers": passengers} but I got and error missing key in map literal.
@tjoe ship1 := map[string]interface{}{ "ship": s1, "crew": crew,"passengers": passengers}

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.