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
https://go.dev/play/p/hK2AdRVsZXJ
CodePudding user response:
You are missing the usage of sort.Reverse() and sort.StringSlice()
func main() {
keys := []string{"bananas", "apples", "oranges"}
sort.Sort(sort.Reverse(sort.StringSlice(keys)))
fmt.Println(keys)
}
https://go.dev/play/p/n08S7xtbeij
See: https://pkg.go.dev/sort#example-Reverse
CodePudding user response:
The arguments are passed as a slice. Collect every other argument as a string and print:
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
}