Cookies management by TermsFeed Cookie Consent
Russia has invaded Ukraine and already killed tens of thousands of civilians, with many more raped or tortured. It's a genocide. We need your help. Let's fight back against the Russian regime.
Help Ukraine! Fight the Russian regime!

🔑 Get a slice of keys from any map using Generics in Go

introduction generics generics-intro

Please consider supporting us by disabling your ad blocker

Before Go 1.18, when you wanted to pull a list of keys from a map in Go, you had to write code that iterated over the map and added the keys to a slice. Since then, with the new Generics feature, you can write a single universal function that gets keys from any map and use it whenever you need it. No more writing code for a specific type of map 😉.

This article is part of the Introduction to Go Generics series. Go here to see more.

Along with the Go 1.18 release, the golang.org/x/exp/maps package has also been released, with the Keys() function working the same as the one below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
    "fmt"
)

func keys[K comparable, V any](m map[K]V) []K {
    keys := make([]K, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}

func main() {
    vegetableSet := map[string]bool{
        "potato":  true,
        "cabbage": true,
        "carrot":  true,
    }

    fruitRank := map[int]string{
        1: "strawberry",
        2: "raspberry",
        3: "blueberry",
    }

    fmt.Printf("vegetableSet keys: %+v\n", keys(vegetableSet))
    fmt.Printf("fruitRank keys: %+v\n", keys(fruitRank))
}

The keys() function takes a map as an argument, in which the keys are of the type with comparable constraint, and the values, with any constraint. As you may already know from our previous tutorial on Generics, the comparable constraint describes types whose values can be compared, meaning that the == and != operators can be used on them. The any constraint is equivalent to interface{} - it accepts any type, so the values of a map can be anything.

The rest of the function is very simple. It returns a slice of keys []K, so in the first line of the function body, the resulting slice is created. Notice that it has a capacity equal to the size of the map. Then, in a loop, each map key is added to the resulting slice. Running the example code with two different maps, you get the output:

vegetableSet keys: [potato cabbage carrot]
fruitRank keys: [1 2 3]

And that’s all. Now, with a single keys() function, you can get a list of keys for any map.

🗑️ Remove duplicates from any slice using Generics in Go

Learn how to create a slice with unique values using Generics
introduction slice generics generics-intro

🔉 Reduce function using Generics in Go

Learn how to define a function to accumulate slice values using Generics
introduction generics generics-intro

🦾 Create a slice 'map' function using Generics in Go

Learn how to apply a function to all slice elements using Generics
introduction generics generics-intro