使用地图按特定顺序插入对象
Insert objects in specific order with map
我有一个用例,其中对象的顺序需要按特定顺序排列。当前的实现是使用 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:true bananas:false oranges:true]
期望的结果:
[oranges:true bananas:false apples:true]
去游乐场
您缺少 sort.Reverse() 和 sort.StringSlice()
的用法
func main() {
keys := []string{"bananas", "apples", "oranges"}
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
fmt.Println(keys)
}
参数作为切片传递。将所有其他参数收集为字符串并打印:
func ProcessFruits(args ...interface{}) interface{} {
var fruits []string
for i, arg := range args {
if i%2 == 0 {
fruits = append(fruits, arg.(string))
}
}
fmt.Println(fruits)
return nil
}
不是最漂亮的解决方案,但我想我已经找到了解决我的问题的有效代码。我所做的是创建另一个字典来跟踪“水果”的顺序,然后将两个字典与嵌套的 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)
}
如果有人有更好的解决方案,那么我很想知道。
我有一个用例,其中对象的顺序需要按特定顺序排列。当前的实现是使用 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:true bananas:false oranges:true]
期望的结果:
[oranges:true bananas:false apples:true]
去游乐场
您缺少 sort.Reverse() 和 sort.StringSlice()
的用法func main() {
keys := []string{"bananas", "apples", "oranges"}
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
fmt.Println(keys)
}
参数作为切片传递。将所有其他参数收集为字符串并打印:
func ProcessFruits(args ...interface{}) interface{} {
var fruits []string
for i, arg := range args {
if i%2 == 0 {
fruits = append(fruits, arg.(string))
}
}
fmt.Println(fruits)
return nil
}
不是最漂亮的解决方案,但我想我已经找到了解决我的问题的有效代码。我所做的是创建另一个字典来跟踪“水果”的顺序,然后将两个字典与嵌套的 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)
}
如果有人有更好的解决方案,那么我很想知道。