2022.05.20  

【Go】mapの中の構造体を順番通りに出力したい

Go    

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}
コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信