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")
}
 
No comments:
Post a Comment