user6791424
user6791424

Reputation:

Unmarshaling JSON top level array into map of string to string

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

Upvotes: 2

Views: 9545

Answers (2)

sberry
sberry

Reputation: 132018

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

Upvotes: 3

Alex Nichol
Alex Nichol

Reputation: 7510

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]

Upvotes: 7

Related Questions