mapの中に複数の構造体Customer
を設定して、そのID順で出力を行いたいとします。
しかし、mapをfor ~range
しても順序が保証されていないため、意図した通りの出力が上手く行えませんでした。(ID: 1,2,3の順で構造体を出力したい)
import "fmt"
type Customer struct {
ID int
Name string
age int
}
func main() {
c1 := &Customer{ID: 1, Name: "taro", age: 23}
c2 := &Customer{ID: 2, Name: "jiro", age: 18}
c3 := &Customer{ID: 3, Name: "subu", age: 10}
customers := make(map[string]Customer)
customers["a"] = *c1
customers["b"] = *c2
customers["c"] = *c3
for _, customer := range customers {
fmt.Printf("%v\n", customer)
}
以下は実行結果。
理想は左の数字を1,2,3の順で出力したい。
{2 jiro 18}
{3 subu 10}
{1 taro 23}
解決策
各CustomerのIDを取り出してソートしたあとに、ソートしたIDとCustomerをID突き合わせて配列に格納すると順序通りに出力が行えます。
package main
import (
"fmt"
"sort"
)
type Customer struct {
ID int
Name string
age int
}
func main() {
c1 := &Customer{ID: 1, Name: "taro", age: 23}
c2 := &Customer{ID: 2, Name: "jiro", age: 18}
c3 := &Customer{ID: 3, Name: "subu", age: 10}
customers := make(map[string]Customer)
customers["a"] = *c1
customers["b"] = *c2
customers["c"] = *c3
// ### 以下コードを追加 ####
// 各customerのIDを配列に格納してソートする
var keys []int
for _, k := range customers {
keys = append(keys, k.ID)
}
// 配列のソート実行
sort.Ints(keys)
// 構造体を格納する配列を定義
var customersList []Customer
// ソートした配列をfor文で回す
for _, key := range keys {
for _, customer := range customers {
// customerのIDとソートしたIDを比較し、一致していたら配列に格納する
if customer.ID == key {
customersList = append(customersList, customer)
break
}
}
}
// customersListに格納したcustomerを順番に出力する
for _, customer := range customersList {
fmt.Printf("%v\n", customer)
}
}
上記のようにコードを書けば出力順序が保証されます。
{1 taro 23}
{2 jiro 18}
{3 subu 10}