Сортировка значений карты Go по ключам


при повторении возвращенной карты в коде, возвращенном функцией topic, ключи не отображаются по порядку.

Как я могу получить ключи, чтобы быть в порядке / сортировать карту так, что ключи в порядке и значения соответствуют?

здесь код.

2 56

2 ответа:

The Go blog: Go maps in action есть отличное объяснение.

при итерации по карте с циклом диапазона порядок итераций равен не указано и не гарантируется от одной итерации к следующему. Так как Go 1 среда выполнения рандомизирует порядок итерации карты, как программисты полагались на стабильный порядок итераций предыдущего реализация. Если вам требуется стабильный порядок итераций, вы должны ведение отдельной структуры данных это определяет этот порядок.

вот моя измененная версия примера кода: http://play.golang.org/p/dvqcGPYy3-

package main

import (
    "fmt"
    "sort"
)

func main() {
    // To create a map as input
    m := make(map[int]string)
    m[1] = "a"
    m[2] = "c"
    m[0] = "b"

    // To store the keys in slice in sorted order
    var keys []int
    for k := range m {
        keys = append(keys, k)
    }
    sort.Ints(keys)

    // To perform the opertion you want
    for _, k := range keys {
        fmt.Println("Key:", k, "Value:", m[k])
    }
}

выход:

Key: 0 Value: b
Key: 1 Value: a
Key: 2 Value: c

по словам Go spec порядок итерации по карте не определена, и может варьироваться между запусками программы. На практике он не только не определен, но и преднамеренно рандомизирован. Это связано с тем, что раньше он был предсказуемым, и разработчики языка Go не хотели, чтобы люди полагались на неопределенное поведение, поэтому они намеренно рандомизировали его, чтобы полагаться на это поведение было невозможно.

то, что вам нужно будет сделать, это потянуть клавиши в срез, сортировать их, а затем диапазон по срезу, как это:

var m map[keyType]valueType
keys := sliceOfKeys(m) // you'll have to implement this
for _, k := range keys {
    v := m[k]
    // k is the key and v is the value; do your computation here
}