LoginSignup
0
0

【Go】マップのキー・バリューを昇順・降順にソートする

Posted at

はじめに

Goのmapは順序を保持しないため、並び替えたい場合はひと工夫が必要です。

以下のようなマップをキー・バリューそれぞれで昇順・降順に並べ替えていきます。

m := map[string]int{
    "Taro":  23,
    "Keiko": 41,
    "Jun":   11,
    "Azusa": 16,
}

// マップは順序を保持しない
for k, v := range m {
    fmt.Printf("Name: %s, Age: %d\n", k, v)
}

image.png

キー(文字列)でソートする

昇順

// 先にキーだけソート
keys := []string{}
for k := range m {
    keys = append(keys, k)
}

// ソート(昇順)
sort.Strings(keys)

// もう一度for-rangeを使い、順に値を取り出す
for _, k := range keys {
    fmt.Printf("Name: %s, Age: %d\n", k, m[k])
}

image.png

降順

// 先にキーだけソート
keys := []string{}
for k := range m {
    keys = append(keys, k)
}

// ソート(降順)
sort.Sort(sort.Reverse(sort.StringSlice(keys)))

// もう一度for-rangeを使い、順に値を取り出す
for _, k := range keys {
    fmt.Printf("Name: %s, Age: %d\n", k, m[k])
}

image.png

バリュー(Int)でソートする

昇順

// 先にバリューだけソート
values := []int{}
for _, v := range m {
    values = append(values, v)
}

// ソート(昇順)
sort.Ints(values)

// valuesが小さい順になっているので、マップのバリューと比較し順に値を取り出す
for _, v := range values {
    for mk, mv := range m {
        if v == mv {
            fmt.Printf("Name: %s, Age: %d\n", mk, mv)
        }
    }
}

image.png

降順

// 先にバリューだけソート
values := []int{}
for _, v := range m {
    values = append(values, v)
}

// ソート(降順)
sort.Sort(sort.Reverse(sort.IntSlice(values)))

// valuesが小さい順になっているので、マップのバリューと比較し順に値を取り出す
for _, v := range values {
    for mk, mv := range m {
        if v == mv {
            fmt.Printf("Name: %s, Age: %d\n", mk, mv)
        }
    }
}

image.png

サンプルコード

サンプルコード全体
package main

import (
	"fmt"
	"sort"
)

func main() {
	m := map[string]int{
		"Taro":  23,
		"Keiko": 41,
		"Jun":   11,
		"Azusa": 16,
	}

	// mapは順序を保持しない
	fmt.Println("初期状態 -------------------------------------")
	for k, v := range m {
		fmt.Printf("Name: %s, Age: %d\n", k, v)
	}

	fmt.Println("キーでソート -------------------------------------")
	// 先にキーだけソート
	keys := []string{}
	for k := range m {
		keys = append(keys, k)
	}

	// ソート
	// 昇順
	sort.Strings(keys)
	// 降順
	// sort.Sort(sort.Reverse(sort.StringSlice(keys)))
	// もう一度for-rangeでソートされた順に値を取り出す
	for _, k := range keys {
		fmt.Printf("Name: %s, Age: %d\n", k, m[k])
	}

	// バリューでソートしたい場合 -------------------------------------
	fmt.Println("バリューでソート -------------------------------------")
	// 先にバリューだけソート
	values := []int{}
	for _, v := range m {
		values = append(values, v)
	}

	// ソート
	// 昇順
	sort.Ints(values)
	// 降順
	// sort.Sort(sort.Reverse(sort.IntSlice(values)))

	// valuesが小さい順になっているので、マップのバリューと比較し順に値を取り出す
	for _, v := range values {
		for mk, mv := range m {
			if v == mv {
				fmt.Printf("Name: %s, Age: %d\n", mk, mv)
			}
		}
	}
}

終わりに

やはりひと手間かかって少し面倒ですね......もっと良い方法があったらぜひ教えてください。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0