SoFunction
Updated on 2025-03-05

Go language map implementation sequential reading

Map in Go is a very powerful data structure that allows us to quickly store and retrieve key-value pairs.

However, when we traverse maps, there is an interesting phenomenon, that is, the order of key-value pairs of outputs is uncertain.

Phenomenon

Let's take a look at a code example:

package main
import "fmt"
func main() {
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "orange": 3,
    }
    for k, v := range m {
        ("key=%s, value=%d\n", k, v)
    }
}

When we execute this code several times more, we will find that the output order is different.

reason

First of all, the underlying implementation of Go language map is a hash table, and when inserting, the key will be hashed. This also leads to the fact that the data is not stored in order and will be inconsistent with the order of traversal.

Second, after map expansion, keys will be relocated. The keys that were originally located in the same bucket. After the relocation, some keys may go to other buckets.

The process of traversal is to traverse buckets in order, and at the same time traverse keys in buckets in order.

After the relocation, the location of the key changed significantly, with some keys being moved away and some keys not moving. In this way, the results of traversing the map cannot be in the original order.

Finally, and the most interesting point.

So if I have initialized a map and do nothing to this map, that is, the capacity expansion will not occur, then is the traversal order fixed?

Answer: No.

Go eliminated this approach, mainly because he was worried that programmers would rely on stable traversal order during development because this was wrong.

Therefore, when traversing maps, it does not start traversing from bucket number 0, each time it starts from a bucket with a random value sequence number, and it starts from a cell with a random sequence number of this bucket.

How to read sequentially

If you want to traverse maps in a specific order, you can first store the keys or values ​​into the slice, then sort the slices, and finally iterate over the slices.

Revise the above code and let it output in order:

package main
import (
    "fmt"
    "sort"
)
func main() {
    m := map[string]int{
        "apple":  1,
        "banana": 2,
        "orange": 3,
    }
    //Storage the keys in the map into slices    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    // Sort the slices    (keys)
    // traverse maps in order after sorting    for _, k := range keys {
        ("key=%s, value=%d\n", k, m[k])
    }
}

In the above code, first store the keys in the map into a slice, and then sort the slices.

Finally, traverse the map in the sorted order. This way you can output key-value pairs in a specific order.

Reference article:

/blog/maps

/go-questions/map/unordered/

This is the article about Go map implementation sequence reading. For more relevant Go map reading content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!