Question

How to Iterate Over Map Keys in Go

goloopsdictionary

Question

In Go, is there a way to get all the keys from a map?

I know len() gives the number of elements, but if I have a map like this:

m := map[string]string{
    "key1": "val1",
    "key2": "val2",
}

How can I iterate over all the keys in the map?

Short Answer

By the end of this page, you will understand how to loop through the keys of a Go map using range, how to collect keys into a slice when needed, why map order is not guaranteed, and how this pattern is used in real Go programs.

Concept

In Go, a map stores key-value pairs. When you want to visit every entry in a map, the usual tool is a for loop with range.

A Go map does not provide a separate built-in "get all keys" function. Instead, you iterate through the map directly:

for key := range m {
    fmt.Println(key)
}

This works because range can loop over maps and return each key one at a time.

If you also need the value, you can write:

for key, value := range m {
    fmt.Println(key, value)
}

This concept matters because maps are used everywhere in Go:

  • configuration lookups
  • counting frequencies
  • caching data
  • grouping records
  • tracking flags or states

Understanding how to iterate over a map is essential for reading, transforming, validating, and exporting data.

One important rule: map iteration order in Go is not guaranteed. If you print keys from a map, they may appear in a different order between runs. If you need a stable order, collect the keys into a slice and sort them.

Mental Model

Think of a Go map like a labeled storage cabinet.

  • The key is the label on a drawer.
  • The value is what is stored inside that drawer.
  • len(m) tells you how many drawers exist.
  • range lets you walk past every drawer and read its label.

If you only care about the labels, you read just the keys. If you care about both the labels and contents, you read both key and value.

The cabinet does not promise that the drawers will appear in alphabetical or insertion order. You are simply visiting all existing drawers in an unspecified order.

Take Quiz

Syntax and Examples

Basic syntax

To iterate over all keys in a Go map:

for key := range m {
    fmt.Println(key)
}

To iterate over keys and values:

for key, value := range m {
    fmt.Println(key, value)
}

Example: print all keys

package main

import "fmt"

func main() {
    m := map[string]string{
        "key1": "val1",
        "key2": "val2",
        "key3": "val3",
    }

    for key := range m {
        fmt.Println(key)
    }
}

This loops through the map and prints each key.

Example: collect keys into a slice

Sometimes you want a list of keys instead of printing them immediately.

package main

import "fmt"

func main() {
    m := map[string]string{
        "key1": "val1",
        "key2": "val2",
        "key3": "val3",
    }

    keys := make([]string, 0, len(m))

    for key := range m {
        keys = append(keys, key)
    }

    fmt.Println(keys)
}

This creates a slice and appends every key from the map.

Example: sorted keys

If you want predictable output order:

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]string{
        "key2": "val2",
        "key1": "val1",
        "key3": "val3",
    }

    keys := make([]string, 0, len(m))
    for key := range m {
        keys = append(keys, key)
    }

    sort.Strings(keys)

    for _, key := range keys {
        fmt.Println(key, m[key])
    }
}

This is the common pattern when order matters.

Step by Step Execution

Consider this example:

package main

import "fmt"

func main() {
    m := map[string]string{
        "name": "Ada",
        "city": "London",
    }

    for key := range m {
        fmt.Println("key:", key)
    }
}

Step by step:

  1. A map named m is created.

  2. It contains two entries:

    • "name" -> "Ada"
    • "city" -> "London"
  3. The loop starts:

    for key := range m {
    
  4. range m asks Go to visit every entry in the map.

  5. On each iteration, Go places the current key into the variable key.

  6. fmt.Println("key:", key) prints that key.

  7. The loop continues until every map entry has been visited.

Possible output:

key: name
key: city

Or:

key: city
key: name

Both are correct, because map iteration order is not guaranteed.

If you wanted both key and value, the loop would be:

for key, value := range m {
    fmt.Println(key, value)
}

Then each iteration gives you two pieces of data instead of one.

Real World Use Cases

Here are common situations where iterating over map keys is useful:

Configuration processing

config := map[string]string{
    "host": "localhost",
    "port": "8080",
}

for key := range config {
    fmt.Println("config key:", key)
}

You may want to validate required settings or print supported options.

Counting and reporting

wordCount := map[string]int{
    "go": 3,
    "map": 2,
}

for word := range wordCount {
    fmt.Println(word)
}

This is useful when generating summaries from counted data.

Building API responses

A service might store fields in a map and iterate over keys to produce output or check allowed fields.

Data validation

You can loop over submitted keys to reject unknown fields:

allowed := map[string]bool{
    "name": true,
    "email": true,
}

submitted := map[string]string{
    "name": "Sam",
    "role": "admin",
}

for key := range submitted {
    if !allowed[key] {
        fmt.Println("unexpected field:", key)
    }
}

Logging and debugging

Developers often inspect maps by iterating over keys and values during debugging or diagnostics.

Take Quiz

Real Codebase Usage

In real Go codebases, developers usually use map iteration in a few standard patterns.

1. Simple traversal

When order does not matter:

for key, value := range m {
    process(key, value)
}

This is the most common pattern.

2. Collect then sort

When output must be deterministic, such as in tests, logs, or generated files:

keys := make([]string, 0, len(m))
for key := range m {
    keys = append(keys, key)
}
sort.Strings(keys)

Then iterate over keys.

3. Validation against known keys

Maps are often used as sets:

allowed := map[string]struct{}{
    "name":  {},
    "email": {},
}

for key := range input {
    if _, ok := allowed[key]; !ok {
        return fmt.Errorf("unknown field: %s", key)
    }
}

This is common in request validation and config parsing.

4. Guard clauses during iteration

Developers often skip invalid entries early:

for key, value := range m {
    if value == "" {
        continue
    }
    fmt.Println(key, value)
}

5. Building derived data

A map may be turned into another structure:

keys := make([]string, 0, len(m))
for key := range m {
    keys = append(keys, key)
}

This is useful for serialization, sorting, filtering, or UI output.

Common Mistakes

Assuming the order is fixed

Broken expectation:

for key := range m {
    fmt.Println(key)
}

A beginner may expect insertion order or alphabetical order. Go does not guarantee either.

How to avoid it:

  • collect keys into a slice
  • sort the slice
  • iterate over the sorted slice

Thinking len(m) gives access to keys

len(m) only tells you how many entries are in the map. It does not provide the keys themselves.

count := len(m)
fmt.Println(count)

This is useful for size, not traversal.

Ignoring the value when you actually need it

If you need both key and value, do not do an extra lookup unless necessary.

Less efficient style:

for key := range m {
    fmt.Println(key, m[key])
}

Better:

for key, value := range m {
    fmt.Println(key, value)
}

Trying to use a nonexistent keys() function

Go maps do not have a built-in keys() method.

Broken code:

keys := m.keys()

Correct approach:

keys := make([]string, 0, len(m))
for key := range m {
    keys = append(keys, key)
}

Forgetting that map keys must match the map type

If your map is map[string]string, then keys are strings.

Broken code:

m := map[string]string{"a": "1"}
for key := range m {
    var n int = key
    fmt.Println(n)
}

This fails because key is a string, not an int.

Modifying logic based on iteration order

Do not write code that depends on the first key being a particular key. That is unreliable unless you sort keys first.

Comparisons

ConceptWhat it doesWhen to use it
len(m)Returns the number of entries in the mapWhen you only need the size
for key := range mIterates over keys onlyWhen you only need keys
for key, value := range mIterates over keys and valuesWhen you need both
Collect keys into a sliceBuilds a reusable list of keysWhen you need to pass keys around
Sort collected keysProduces deterministic orderWhen order matters

range over map vs range over slice

StructureOrder guaranteed?Returned values
MapNoKey, value
SliceYes, by index orderIndex, value

Keys only vs keys and values

for key := range m {
    fmt.Println(key)
}

Use this when you only care about keys.

for key, value := range m {
    fmt.Println(key, value)
}

Use this when you need both and want cleaner code.

Take Quiz

Cheat Sheet

// Iterate over keys only
for key := range m {
    fmt.Println(key)
}

// Iterate over keys and values
for key, value := range m {
    fmt.Println(key, value)
}

// Get number of entries
n := len(m)

// Collect keys into a slice
keys := make([]string, 0, len(m))
for key := range m {
    keys = append(keys, key)
}

Rules to remember

  • Go maps are iterated with for ... range.
  • len(m) gives the count, not the keys.
  • Map iteration order is not guaranteed.
  • If order matters, collect keys and sort them.
  • Use for key, value := range m when you need both pieces of data.

Common pattern for sorted output

keys := make([]string, 0, len(m))
for key := range m {
    keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
    fmt.Println(key, m[key])
}

FAQ

How do I loop through all keys in a Go map?

Use for key := range m {}.

Can I get all map keys as a slice in Go?

Yes. Create a slice, then append each key while ranging over the map.

Does Go preserve map insertion order?

No. Map iteration order is not guaranteed.

How do I print both keys and values from a Go map?

Use for key, value := range m {}.

Is there a built-in function to return map keys in Go?

No built-in map method returns all keys directly. You iterate with range.

Why is my map output order changing?

Because Go maps do not guarantee iteration order. Sort the keys if you need stable output.

Take Quiz

Mini Project

Description

Build a small Go program that stores environment settings in a map, prints all available setting names, and then prints them again in sorted order. This demonstrates basic map key iteration and the common real-world need for deterministic output.

Goal

Create a program that iterates over all keys in a map and also produces a sorted list of those keys.

Requirements

  1. Create a map[string]string with at least four configuration entries.
  2. Print all keys using a for ... range loop.
  3. Collect the keys into a slice.
  4. Sort the slice alphabetically.
  5. Print each sorted key together with its value.
Take Quiz

Keep learning

Related questions

View more