SSブログ

golangのmapのvalueにスライスを使えた。 [プログラミング]

いわゆる辞書型とかハッシュとか言われるものが、Golangではmap(連想配列)なわけだが、mapをスライスにするとかいう話しかあまり出てこなくて、key, valueのvalueの方を配列やスライスにするやり方とかがすぐに出てこなかった。

結局、自分で試してみてmapのvalue側を多値にできる事がわかったんだけど、一般的には最初に考えていたようにkey(配列とスライス以外)とvalue(スライス)を構造体に入れて、構造体をスライスにしてそれぞれにアクセスという事をしているのかなと思ったりした。内部的にはそれと同じ事をしているのかもしれないけど…。


普通のmapは
m := map[string]string{"key1": "value1", "key2": "value2", "key3": "value3"}

って感じで「一対一」なんだけど、自分は「一対多」のmapが欲しかった。それもvalueの方の多が変動してもいいようになってほしかった。できないかなと思っていたけど、普通にできた。言語的な限界とか変な意地悪とかはなくてよかった。

んで実際にどうするのか、というところだけどポインタとかで持たせることなく、普通にスライスにするだけで使える。
m := map[string] []string{}
m["hoge"] = []string{"value1", "value2", "value3"}
m["foo"] = []string{"value4"}
m["bar"] = []string{"value5", "value6"}

って入れられるので、1対多でも数が揃っていなくてOK。これをforループを二つ使えば、keyごとのvalueの同様の処理がザラっとできる。

何が便利かというとkeyでまとめられた処理を行なって、その後にvalueで個別に処理できる、というところだ。数があってなくても統一された処理を行えるので、個数が可変の処理が可能となる。ひとまとまりのグループ同士が数が揃ってないけど、処理は統一してやっちゃいたいという場合は重宝する。先のソースを続けていくと、

package main

import "fmt"

func main() {
	m := map[string][]string{}
	m["hoge"] = []string{"value1", "value2", "value3"}
	m["foo"] = []string{"value4"}
	m["bar"] = []string{"value5", "value6"}

	for key, value := range m {
		fmt.Println("key: " + key)
		for i, v := range value {
			fmt.Println(i, v)
		}
		fmt.Println()
	}
}


goのファイル名が適当ですまないけど、実行結果は下記のように出る。

$ go run package_main.go 
key: hoge
0 value1
1 value2
2 value3

key: foo
0 value4

key: bar
0 value5
1 value6

データの数がバラバラでも簡単な処理で画一に処理することができる。スライスを持つmapは一般的ではないのかな? 探し方が甘かったのかな? でも自分で色々やって解決するってプログラミングしている感じがして楽しい。

タグ:Golang
コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0