Home > Software engineering >  Insert objects in specific order with map
Insert objects in specific order with map

Time:02-24

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
}
  • Related