Golang 1.23 Added new slices functions to help sort. These are useful for sorting maps by values or by keys.
In my previous post I went through some examples about how to sort by the keys of a map and return an array of values.
This does the converse and I provide examples to sort by the values of a map and return an array of keys.
https://www.geeksforgeeks.org/how-to-sort-golang-map-by-keys-or-values/ was helpful to see how to do it using the sort package. When I looked at the api docs, it suggested using the slices package:
"Note: in many situations, the newer slices.SortStableFunc function is more ergonomic and runs faster."
// Sort by value with map[int]string and map[string]int
func main() {
fmt.Println("Start")
fmt.Println("Sorting by Value in a map with int keys and string values")
intStringMap := map[int]string{
22: "z",
111: "y",
3333: "x",
}
// 1) Using sort package
intKeys := slices.Collect(maps.Keys(intStringMap))
sort.SliceStable(intKeys, func(i, j int) bool {
return intStringMap[intKeys[i]] < intStringMap[intKeys[j]]
})
fmt.Println("1) Using sort package:", intKeys) // [3333 111 22]
// 2) Using slices package
intKeySlice := slices.Collect(maps.Keys(intStringMap))
slices.SortStableFunc(intKeySlice, func(a, b int) int {
return cmp.Compare(intStringMap[a], intStringMap[b])
})
fmt.Println("2) Sort Keys in place", intKeySlice) // [3333 111 22]
fmt.Println()
fmt.Println("Sorting by Value in a map with string keys and int values")
stringIntMap := map[string]int{
"z": 222,
"y": 11,
"x": 3333,
}
// 1) Using sort package. API says consider using slices package
stringKeys := slices.Collect(maps.Keys(stringIntMap))
sort.SliceStable(stringKeys, func(i, j int) bool {
return stringIntMap[stringKeys[i]] < stringIntMap[stringKeys[j]]
})
fmt.Println("1) Using sort package:", stringKeys) // [y z x]
// 2) returns a slice where the values are the keys of stringIntMap
// sorts the keys in place
keySlice := slices.Collect(maps.Keys(stringIntMap))
slices.SortStableFunc(keySlice, func(a, b string) int {
return cmp.Compare(stringIntMap[a], stringIntMap[b])
})
fmt.Printf("2) Sort In Place: %v\n", keySlice) // [y z x]
// 3) returns a slice where the values are the keys of stringIntMap
keys := maps.Keys(stringIntMap) // an Iter
keysSortedByValue := slices.SortedStableFunc(keys, func(a, b string) int {
return cmp.Compare(stringIntMap[a], stringIntMap[b])
})
fmt.Printf("3) New Variable: %v\n", keysSortedByValue) // [y z x]
// Output the keys and values
fmt.Println("Print the stringIntMap in order")
for _, k := range keysSortedByValue {
fmt.Printf("%s: %d\n", k, stringIntMap[k])
}
// y: 11
// z: 222
// x: 3333
fmt.Println("Done")
}