Golang中Sorted maps和slices每次编译结果不同如何解决
Golang中Sorted maps和slices每次编译结果不同如何解决 大家好,
有人能帮我理解一下下面这段代码是怎么回事吗?我不明白为什么每次运行它都会得到不同的结果。我的目标是创建一个映射(map)并按键排序,然后我想将其值收集到一个切片(slice)中。
package main
import (
"fmt"
"sort"
)
func main() {
map1 := make(map[uint16][]byte)
map1[264] = []byte{4, 6, 2, 7}
map1[85] = []byte{99, 65, 4, 11, 22}
map1[668] = []byte{44, 25, 47, 23, 72, 63, 48}
map1[32] = []byte{19, 63, 40}
fmt.Println(map1)
keys := make([]uint16, 0)
for key := range map1 {
keys = append(keys, key)
}
fmt.Println("keys: ", keys)
sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
fmt.Println("sorted keys: ", keys)
sort_map := make(map[uint16][]byte)
for k := range keys {
sort_map[keys[k]] = map1[keys[k]]
}
fmt.Println(sort_map)
for k, v := range sort_map {
fmt.Println(k, v)
}
total_data := make([]byte, 0)
for _, v := range sort_map {
total_data = append(total_data, v...)
}
fmt.Println(total_data)
for i := range total_data {
x := total_data[i]
fmt.Println(x)
}
}
非常感谢您的帮助,我真的很感激。
更多关于Golang中Sorted maps和slices每次编译结果不同如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
是的,非常感谢您的帮助
更多关于Golang中Sorted maps和slices每次编译结果不同如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Map 是不可排序的。你可以改为对键的切片进行排序,就像你已经在做的那样,然后每当需要按顺序获取数据时,就遍历该切片。
我不太确定我理解你想要做什么,但我移除了 sort_map 并想出了这个。这是你想要的吗?
非常感谢您的快速回复。我已经按照您说的做了,但不知道为什么每次编译都会得到不同的结果。
这个结果是正确的

而这两个结果是不正确的。

在Go语言中,map的迭代顺序是非确定性的,这是设计上的特性。你遇到的问题根源在于:虽然你创建了排序后的键切片,但在填充sort_map时,仍然使用了for k := range keys这种顺序迭代,这本身是确定性的。然而,问题出在最后遍历sort_map时,你使用了for _, v := range sort_map,这又会回到map的非确定性迭代上。
以下是修改后的代码,关键点在于:直接使用已排序的键切片来访问值,而不是再次遍历map。
package main
import (
"fmt"
"sort"
)
func main() {
map1 := make(map[uint16][]byte)
map1[264] = []byte{4, 6, 2, 7}
map1[85] = []byte{99, 65, 4, 11, 22}
map1[668] = []byte{44, 25, 47, 23, 72, 63, 48}
map1[32] = []byte{19, 63, 40}
// 提取并排序键
keys := make([]uint16, 0, len(map1))
for key := range map1 {
keys = append(keys, key)
}
sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
// 直接使用排序后的键来构建有序切片
total_data := make([]byte, 0)
for _, key := range keys {
total_data = append(total_data, map1[key]...)
}
fmt.Println("Sorted keys:", keys)
fmt.Println("Total data (in order of sorted keys):", total_data)
// 如果需要验证,按顺序打印
for _, key := range keys {
fmt.Printf("Key %d: %v\n", key, map1[key])
}
}
如果你确实需要一个保持插入顺序的map结构,可以使用第三方库如github.com/elliotchance/orderedmap,但针对你的需求,直接使用排序后的键切片访问原始map是最简洁的方案。

