2

I'm trying to unmarshal a JSON array of the following type:

[
{"abc's": "n;05881364"},
{"abcoulomb": "n;13658345"},
{"abcs": "n;05881364"}
]

into a map[string]string. This question Golang parse JSON array into data structure almost answered my problem, but mine is a truly map, not an array of maps. Unmarshaling into a []map[string]string worked but I now get a map of map[string]string, not a simple map of string as it should be

4
  • 3
    The JSON shown is an array of maps where each map has a single key/value pair. If you want to create a map[string]string out of that, you'll have to unmarshal it into an array of maps and then create a single map from that. Commented Feb 17, 2017 at 5:08
  • @AndySchweig so there's no direct way? Commented Feb 17, 2017 at 5:12
  • @AndySchweig I thought there way a better way instead of looping through every map element and extracting its key and value and adding to a new map Commented Feb 17, 2017 at 5:13
  • 4
    Whatever you unmarshal into has to have the same structure as the JSON. Why is the JSON structured as an array of maps if it's supposed to be a single map? Commented Feb 17, 2017 at 5:57

2 Answers 2

7

There is no way to do it directly with the json package; you have to do the conversion yourself. This is simple:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    data := []byte(`
        [
        {"abc's": "n;05881364"},
        {"abcoulomb": "n;13658345"},
        {"abcs": "n;05881364"}
        ]
    `)

    var mapSlice []map[string]string
    if err := json.Unmarshal(data, &mapSlice); err != nil {
        panic(err)
    }
    resultingMap := map[string]string{}
    for _, m := range mapSlice {
        for k, v := range m {
            resultingMap[k] = v
        }
    }
    fmt.Println(resultingMap)
}

Output

map[abc's:n;05881364 abcoulomb:n;13658345 abcs:n;05881364]
Sign up to request clarification or add additional context in comments.

Comments

3

An alternative (though very similar) to Alex's answer is to define your own type along with an UnmarshalJSON function.

package main

import (
    "encoding/json"
    "fmt"
)

type myMapping map[string]string

func (mm myMapping) UnmarshalJSON(b []byte) error {
    var temp []map[string]string
    if err := json.Unmarshal(b, &temp); err != nil {
        return err
    }
    for _, m := range temp {
        for k, v := range m {
            mm[k] = v
        }
    }
    return nil
}

func main() {
    data := []byte(`
            [
                {"abc's": "n;05881364"},
                {"abcoulomb": "n;13658345"},
                {"abcs": "n;05881364"}
            ]`)

    resultingMap := myMapping{}
    if err := json.Unmarshal(data, &resultingMap); err != nil {
        panic(err)
    }
    fmt.Println(resultingMap)
}

Playground

Comments

Your Answer

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