🐙

Goでキーが不定のjsonを扱う

2021/06/13に公開

Goでjsonを扱う時に調査したことのメモ。

jsonのキーが固定のとき

取得するjsonのキーがわかっている時は構造体を用意して、json.Unmarshalを使用するのが結果も扱いやすくよく利用します。

users.json
[
  {
    "id": 1,
    "name": "Tanaka",
    "age": 20
  },
  {
    "id": 2,
    "name": "Yamada",
    "age": 23
  }
]
main.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type User struct {
	Id   int    `json:"id"`
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	bytes, err := ioutil.ReadFile("users.json")
	if err != nil {
		log.Fatal(err)
	}

	var users []User
	if err := json.Unmarshal(bytes, &users); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%v\n", users)
}

キーが不定のとき

事前にキーが分からない場合は上記の方法だと対応が難しい場合があります。(今回の例だとscore)。
そういうときは、mapで対応する。
[]map[string]interface{}を用意してjson.Unmarshalに渡す。そうすることで結果のようなmapになる。

users.json
[
  {
    "id": 1,
    "name": "Tanaka",
    "age": 20,
    "score": {
      "2021_01": 40,
      "2021_03": 50
    }
  },
  {
    "id": 2,
    "name": "Yamada",
    "age": 23,
    "score": {
      "2020_01": 40,
      "2021_06": 90
    }
  }
]
main.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

func main() {
	bytes, err := ioutil.ReadFile("users.json")
	if err != nil {
		log.Fatal(err)
	}

	var result []map[string]interface{}
	json.Unmarshal(bytes, &result)
	fmt.Printf("%v\n", result)
}

結果

[map[age:20 id:1 name:Tanaka score:map[2021_01:40 2021_03:50]] map[age:23 id:2 name:Yamada score:map[2020_01:40 2021_06:90]]]

Discussion