🐱

Golang : how to access nested map

2022/11/03に公開約2,600字

概要

ネストされたマップの値に,任意の数のキーを指定し,アクセスできる関数である.

code

package main

import (
	"encoding/json"
	"errors"
	"fmt"
)

// json sample https://json.org/example.html
const (
	sampleJson = `{
    "glossary": {
        "title": "example glossary",
		"GlossDiv": {
            "title": "S",
			"GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
					"SortAs": "SGML",
					"GlossTerm": "Standard Generalized Markup Language",
					"Acronym": "SGML",
					"Abbrev": "ISO 8879:1986",
					"GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
						"GlossSeeAlso": ["GML", "XML"]
                    },
					"GlossSee": "markup"
                }
            }
        }
    }
}`
)

func main() {
	var nestedMap map[string]interface{}
	err := json.Unmarshal([]byte(sampleJson), &nestedMap)
	if err != nil {
		fmt.Println(err)
		panic(1)
	}
	// normal access
	fmt.Println(nestedMap["glossary"])
	fmt.Println(nestedMap["glossary"].(map[string]interface{})["title"])

	// using lookupNnestedMap
	fmt.Println(lookupNestedMap(nestedMap, "glossary"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "title"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "title"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "ID"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "SortAs"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "GlossTerm"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "Acronym"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "Abbrev"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "GlossDef"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "GlossDef", "para"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "GlossDef", "GlossSeeAlso"))
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "GlossDiv", "GlossList", "GlossEntry", "GlossSee"))

	// no data case
	fmt.Println(lookupNestedMap(nestedMap, "glossary", "hello world")) // no  data
}

func lookupNestedMap(nestedMap map[string]interface{}, keys ...string) interface{} {
	val, ok := nestedMap[keys[0]]
	if !ok || len(keys) == 0 {
		return errors.New("no data")
	}
	if len(keys) == 1 {
		return val
	}
	return lookupNestedMap(val.(map[string]interface{}), keys[1:]...)
}

references

https://json.org/example.html

Discussion

ログインするとコメントできます