使用地图按特定顺序插入对象
我有一个用例,其中对象的顺序需要按特定顺序。当前的实现是使用 map
完成的,我发现许多帖子和文章都指出 map
是一个无序列表。我发现的所有解决方案都是将键设置为整数,并使用 sort.Ints(keys)
按键排序。
在代码中,我使用 yaml 模板实例化一个字典对,然后将其传递到 ProcessFruits 函数,在其中执行逻辑。
我将如何获得所需的结果(见下文),其中fruits.yml.tmpl 中列表顶部的对象始终是第一个?
这是我的代码的简化版本:
//Filename: fruits.yml.tmpl
fruits: {{ $fruits := processFruits
"oranges" true
"bananas" false
"apples" true
}}
{{ $fruits }}
//Filename: fruits.go
func ProcessFruits(fruits map[string]interface{}) (interface{}) {
keys := make([]string, len(fruits))
i := 0
for fruit := range fruits {
keys[i] = fruit
i++
}
sort.Strings(keys)
fmt.Println(keys)
}
// Connect fruits.yml.tmpl to the ProcessFruits function
tmpl, err := template.New(t).Funcs(template.FuncMap(map[string]interface{}{
"processFruits": ProcessFruits,
})).Funcs(sprig.TxtFuncMap())
实际结果:
[apples:truebananas:falseoranges:true]
期望结果:
[oranges:truebananas:falseapples:true]
Go Playground
I have a use case where the order of objects needs to be in a specific order. The current implementation is done with using map
and I've found numerous posts and articles where it states that map
are an unordered list. All of the solutions that I found are those where they've made the keys as integers and they've used sort.Ints(keys)
to sort by keys.
In the code, I'm using a yaml template to instantiate a dictionary pair, then passing it into the ProcessFruits function where it does the logic.
How would I go about getting the desired result (see below) where the object from the top of the list in fruits.yml.tmpl will always be first?
Here's a simplified version of my code:
//Filename: fruits.yml.tmpl
fruits: {{ $fruits := processFruits
"oranges" true
"bananas" false
"apples" true
}}
{{ $fruits }}
//Filename: fruits.go
func ProcessFruits(fruits map[string]interface{}) (interface{}) {
keys := make([]string, len(fruits))
i := 0
for fruit := range fruits {
keys[i] = fruit
i++
}
sort.Strings(keys)
fmt.Println(keys)
}
// Connect fruits.yml.tmpl to the ProcessFruits function
tmpl, err := template.New(t).Funcs(template.FuncMap(map[string]interface{}{
"processFruits": ProcessFruits,
})).Funcs(sprig.TxtFuncMap())
Actual Results:
[apples:true bananas:false oranges:true]
Desired Results:
[oranges:true bananas:false apples:true]
Go Playground
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(3)
这不是最漂亮的解决方案,但我想我已经找到了解决我的问题的工作代码。我所做的是创建另一个字典来跟踪“水果”的顺序,然后将两个字典与嵌套的 for 循环组合在一起,并将结果输出到切片。
这是我的代码:
package main
import (
"fmt"
"sort"
)
func ProcessFruits(fruits map[string]interface{}, counts map[int]string) {
keys := make([]string, len(fruits))
var foo []string
var baz []int
for k := range fruits {
foo = append(foo, k)
}
for _, k := range foo {
fmt.Println("Key-string:", k, "Value-bool:", fruits[k])
}
fmt.Println("==========================")
// Iterate over counts (keys are ints)
for l := range counts {
baz = append(baz, l)
}
sort.Ints(baz)
for _, l := range baz {
fmt.Println("Key-int:", l, "Value-string:", counts[l])
}
fmt.Println("==========================")
// Correlate list with sorted integer keys with the other list that contains true/false
i := 0
for _, m := range baz {
for _, n := range foo {
//fmt.Println("Key-int:", m, "Value-string:", counts[m])
//fmt.Println("Key-string:", n, "Value-bool:", fruits[n])
if counts[m] == n {
keys[i] = n
i++
//fmt.Println(i)
}
}
}
// Desired results is now in the slice, keys.
fmt.Println(keys)
}
func main() {
var m = map[string]interface{}{
"oranges": true,
"bananas": false,
"apples": true,
}
var n = map[int]string{
0: "oranges",
1: "bananas",
2: "apples",
}
ProcessFruits(m, n)
}
如果有人有更好的解决方案,那么我很想知道。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您缺少 sort.Reverse() 和 sort.StringSlice() 的用法
https://go.dev /play/p/n08S7xtbeij
请参阅:https://pkg.go.dev/sort#example-Reverse
You are missing the usage of sort.Reverse() and sort.StringSlice()
https://go.dev/play/p/n08S7xtbeij
See: https://pkg.go.dev/sort#example-Reverse