如何根据另一个地图的键值对 Go 中的地图进行排序?
How do I sort a map in Go based on another map's key values?
我需要根据另一个地图的键对地图进行排序,因为我当前的函数 returns 地图未排序,所以我需要它根据名称的顺序保持一致,如中所示reference
。我知道一些排序功能,但是,我在实现它们时遇到了一些麻烦。重申一下,我需要按照与 reference
变量相同的方式对名称进行排序;没有仅基于一个特定地图排序的字母顺序。如果有人能帮忙解决这个问题就太好了。
为了澄清,我需要根据与 reference
相同的顺序对 testMap() 和 testMap2() 的返回值进行排序。 reference
变量显示了两个名称之间的联系(命名约定的差异)。
package main
import (
"fmt"
)
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
testMap()
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
初步说明
重申评论中的重要内容:Go 中的映射没有定义的顺序,因此您无法对它们进行排序或保证它们的顺序。
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. If you require a stable iteration order you must maintain a separate data structure that specifies that order.
回答
您可以遍历 reference
中的 keys/values 并使用第一个和第二个键从第一个和第二个映射中获取值。
package main
import (
"fmt"
)
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
m1 := testMap()
m2 := testMap2()
for key1, key2 := range reference {
v1, _ := m1[key1]
v2, _ := m2[key2]
fmt.Printf("%s/%s: (%d, %d)\n", key1, key2, v1, v2)
// not sure what you want with these, so I'm just printing
}
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
请注意,这仍然不能保证顺序,只是“匹配”键的值是成对的。
如果你想要秩序,你需要有秩序的东西(例如一片)。例如:
package main
import (
"fmt"
)
var keyOrder = []string{"Ali", "Cat", "Bob"}
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
m1 := testMap()
m2 := testMap2()
for _, key1 := range keyOrder {
key2, _ := reference[key1]
v1, _ := m1[key1]
v2, _ := m2[key2]
fmt.Printf("%s/%s: (%d, %d)\n", key1, key2, v1, v2)
}
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
或者您可以将 reference
更改为如下所示:
var reference = [][]string{{"Ali", "Ali_1"}, {"Cat", "Cat1"}, {"Bob", "Bob"}}
(如果你涉及两个以上的地图,这会更灵活,但你必须确保子切片中的顺序与地图顺序匹配。)
尽管随着我们的进步,这会越来越多。您可能会考虑完全不同的方法,可能会使用更复杂的类型,如结构或其他东西。或者退后一步,首先考虑一下为什么会有这些不匹配的密钥。
我需要根据另一个地图的键对地图进行排序,因为我当前的函数 returns 地图未排序,所以我需要它根据名称的顺序保持一致,如中所示reference
。我知道一些排序功能,但是,我在实现它们时遇到了一些麻烦。重申一下,我需要按照与 reference
变量相同的方式对名称进行排序;没有仅基于一个特定地图排序的字母顺序。如果有人能帮忙解决这个问题就太好了。
为了澄清,我需要根据与 reference
相同的顺序对 testMap() 和 testMap2() 的返回值进行排序。 reference
变量显示了两个名称之间的联系(命名约定的差异)。
package main
import (
"fmt"
)
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
testMap()
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
初步说明
重申评论中的重要内容:Go 中的映射没有定义的顺序,因此您无法对它们进行排序或保证它们的顺序。
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. If you require a stable iteration order you must maintain a separate data structure that specifies that order.
回答
您可以遍历 reference
中的 keys/values 并使用第一个和第二个键从第一个和第二个映射中获取值。
package main
import (
"fmt"
)
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
m1 := testMap()
m2 := testMap2()
for key1, key2 := range reference {
v1, _ := m1[key1]
v2, _ := m2[key2]
fmt.Printf("%s/%s: (%d, %d)\n", key1, key2, v1, v2)
// not sure what you want with these, so I'm just printing
}
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
请注意,这仍然不能保证顺序,只是“匹配”键的值是成对的。
如果你想要秩序,你需要有秩序的东西(例如一片)。例如:
package main
import (
"fmt"
)
var keyOrder = []string{"Ali", "Cat", "Bob"}
var reference = map[string]string{"Ali": "Ali_1", "Cat": "Cat1", "Bob": "Bob"}
func main() {
m1 := testMap()
m2 := testMap2()
for _, key1 := range keyOrder {
key2, _ := reference[key1]
v1, _ := m1[key1]
v2, _ := m2[key2]
fmt.Printf("%s/%s: (%d, %d)\n", key1, key2, v1, v2)
}
}
func testMap() map[string]int {
return map[string]int{"Ali_1": 2, "Bob": 3, "Cat1": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
func testMap2() map[string]int {
return map[string]int{"Ali": 2, "Bob": 3, "Cat": 3} // goal is to sort this in the same order of keys(names) as the reference variable
}
或者您可以将 reference
更改为如下所示:
var reference = [][]string{{"Ali", "Ali_1"}, {"Cat", "Cat1"}, {"Bob", "Bob"}}
(如果你涉及两个以上的地图,这会更灵活,但你必须确保子切片中的顺序与地图顺序匹配。)
尽管随着我们的进步,这会越来越多。您可能会考虑完全不同的方法,可能会使用更复杂的类型,如结构或其他东西。或者退后一步,首先考虑一下为什么会有这些不匹配的密钥。