【golang】mapの要素順は変動する
投稿日:
■環境
OS X El Capitan 10.11.6
go 1.8 darwin/amd64
タイトルの件、ちょっと引っかかったのでメモです。
golangで変数にmapを格納する場合、その要素の順番は
呼び出すたびに変わります。
以下サンプルコードです。
mapをrangeで取り出しながらforで回し、標準出力する
という処理を3回繰り返します。
package main
import (
"fmt"
)
func main() {
// create new map
fruitColor := make(map[string]string)
fruitColor["pineapple"] = "yellow"
fruitColor["apple"] = "red"
fruitColor["grape"] = "purple"
fruitColor["melon"] = "green"
// printout 3 times
for i := 1; i <= 3; i++ {
fmt.Println(fmt.Sprintf("===== %d times =====", i))
for name, color := range fruitColor {
fmt.Println(fmt.Sprintf("%s is %s", name, color))
}
}
}
これを実行すると、このように出力されます。
要素順は変動するので、実行する度に変わると思います。
===== 1 times =====
apple is red
grape is purple
melon is green
pineapple is yellow
===== 2 times =====
grape is purple
melon is green
pineapple is yellow
apple is red
===== 3 times =====
melon is green
pineapple is yellow
apple is red
grape is purple
上記のような順不同なアプリケーションだとしても、
ユーザが画面を表示する度に順番が変わるのは気持ち悪いので
sliceを使って表示順を保持しておいた方が良いです。
sliceを使う例は以下の通りです。
package main
import (
"fmt"
)
func main() {
// create new map
fruitColor := make(map[string]string)
fruitColor["pineapple"] = "yellow"
fruitColor["apple"] = "red"
fruitColor["grape"] = "purple"
fruitColor["melon"] = "green"
// set display order
fruitList := []string{"pineapple","apple","grape","melon"}
// printout 3 times
for i := 1; i <= 3; i++ {
fmt.Println(fmt.Sprintf("===== %d times =====", i))
for _, name := range fruitList {
fmt.Println(fmt.Sprintf("%s is %s", name, fruitColor[name]))
}
}
}
これを実行すると以下のようになります。
===== 1 times =====
pineapple is yellow
apple is red
grape is purple
melon is green
===== 2 times =====
pineapple is yellow
apple is red
grape is purple
melon is green
===== 3 times =====
pineapple is yellow
apple is red
grape is purple
melon is green