As a person who came to Go world from PHP, I had some troubles when I tried to iterate over previously generated map, because of

assuming that the order of items will be the same with an order with was used during map generation. 

Let's check an example:

package main


import (
    "fmt"
)


func main() {
    // Generates items map with 10 elements.
    items := make(map[int]string)
    for i := 0; i < 10; i++ {
        items[i] = fmt.Sprintf("This is item %d", i)
    }
    // Processes items from map.
    for _, item := range items {
        performItem(item)
    }
}


func performItem(item string) {
    fmt.Println(item)
}

The result of execution will be:

This is item 5
This is item 7
This is item 0
This is item 3
This is item 4
This is item 8
This is item 9
This is item 1
This is item 2
This is item 6

After second execution:

This is item 7
This is item 8
This is item 9
This is item 2
This is item 5
This is item 6
This is item 4
This is item 0
This is item 1
This is item 3

As you can see, order of items completely random and does not match with order what we used during generation. This was a little bit strange.

But then I found a fair answer why this is happening:

Programmers had begun to rely on the stable iteration order of early versions of Go, which varied between implementations, leading to portability bugs. If you require a stable iteration order you must maintain a separate data structure that specifies that order.

So, what we can do to process items accordingly to our order?

We just have to sort our keys separately and iterate over our map, using sorted keys:

package main

import (
    "fmt"
    "sort"
)

func main() {
    items := make(map[int]string)
    for i := 0; i < 10; i++ {
        items[i] = fmt.Sprintf("This is item %d", i)
    }

    // Generates keys map.
    keys := make([]int, len(items))
    for k := range items {
        keys[k] = k
    }
    sort.Ints(keys)
    // Iterates over items map, using sorted keys.
    for _, k := range keys {
        performItem(items[k])
    }
}

func performItem(item string) {
    fmt.Println(item)
}

Let's execute it:

This is item 0
This is item 1
This is item 2
This is item 3
This is item 4
This is item 5
This is item 6
This is item 7
This is item 8
This is item 9

Now it looks perfect!


Source code you can found here