-2

I want to sort this map by value,in descending order( from the most of like to the less of likes ) and put it on the same map or another one with this ordre My map:

   m := make(map[int]int)
   for train := range *trainings{
   l,_:= db.NumberOfLikes(train,train.TrainingId)
   m[train.TrainingId]=l
   }

How can I do it?

Mizleug
  • 23
  • 1
  • 6

1 Answers1

1

The [Go blog: Go maps in action][1] has an excellent explanation.

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. Since Go 1 the runtime randomizes map iteration order, as programmers relied on the stable iteration order of the previous implementation. If you require a stable iteration order you must maintain a separate data structure that specifies that order.

m := map[string]int{"Alice": 23, "Eve": 2, "Bob": 25}

keys := make([]string, 0, len(m))
for k := range m {
    keys = append(keys, k)
}
sort.Strings(keys)

for _, k := range keys {
    fmt.Println(k, m[k])
}
alessiosavi
  • 2,753
  • 2
  • 19
  • 38
  • here he does copy the values in an array and sort the array and display values, he doesn't sort the map – Mizleug Sep 11 '20 at 10:30
  • I think that you have not read the explaination: `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` – alessiosavi Sep 11 '20 at 10:32
  • 1
    A map in Go cannot be sorted, so this is the correct answer. – TehSphinX Sep 11 '20 at 10:40
  • but a slice can't contain both the id and the number of like that this training has , or am I wrong ? @TehSphinX – Mizleug Sep 11 '20 at 10:45
  • A slice can contain structs that can contain any information you need. You can create a struct type `Training` that has the ID and all training data in it. Then you can create `var trainings []Training` and you can sort that with `sort.Slice` and a custom sort function. e.g. by ID: `sort.Slice(trainings, func(i, j int) bool {return trainings[i].ID < trainings[j].ID})` – TehSphinX Sep 11 '20 at 11:06
  • Thank you very much for your help, but likes aren't in training data, to contextualize, I have a struct with all training data (Training id, date, .... but doesn't contain likes) , and I have a separate stuct for likes that has the training id and some other information in it , and I need to sort and display trainings by number of likes @TehSphinX – Mizleug Sep 11 '20 at 11:20
  • Then maybe your data could look like this: `var trainings []struct { Likes int training Training }` – TehSphinX Sep 11 '20 at 12:39