Hi guys... Is there a way to sort a map/Hashmap us...
# announcements
l
Hi guys... Is there a way to sort a map/Hashmap using both the keys and values. For instance:
Copy code
``[Elijah=51, Chloe=144, Natalie=207, Jayden=390, Elizabeth=485, Matthew=485]``
In this map, I would like values to be sorted in a descending order first. Then sort the keys in an alphabetical order. i.e
``Elizabeth``
must appear before
``Matthew``
even though their values are the same. 🤷‍♂️
n
Hashmap can't be sorted at all because of how it works... You can use a TreeMap to define your custom sorting order
m
Copy code
``````val map = mapOf(
"Elijah" to 51, "Chloe" to 144, "Natalie" to 207, "Jayden" to 390, "Matthew" to 485, "Elizabeth" to 485,
)
val sortedMap = map
.toList()
.sortedWith(compareBy<Pair<String,Int>> { it.second }.thenBy { it.first })
.toMap()``````
l
@Marc Knaup, your solution results to
Copy code
``{Elijah=51, Chloe=144, Natalie=207, Jayden=390, Elizabeth=485, Matthew=485}``
n
(note that the
``toMap``
does not return a
``HashMap``
which does not have its fast amortized O(1) look up time)
m
@linus muema I’ve missed the “descending” 🙂
Copy code
``````val map = mapOf(
"Elijah" to 51, "Chloe" to 144, "Natalie" to 207, "Jayden" to 390, "Matthew" to 485, "Elizabeth" to 485,
)
val sortedMap = map
.toList()
.sortedWith(compareByDescending<Pair<String,Int>> { it.second }.thenBy { it.first })
.toMap()``````
@Niklas Gürtler
``toMap()``
uses
``LinkedHashMap``
which should also have O(1) lookup. It just uses more memory to maintain order.
l
@Marc Knaup It works...Thanks a lot K
👍 1
n
Right, that's basically a HashMap + Linked list so technically the HashMap is still not sorted 😉 but right, that's a good solution
i
Could it be a bit simplified using
``entries``
``toList``
?
m
Then you won’t have a convenient
``toMap()``
at the end which operates on
``Iterable<Pair<…>>``
i
Got it, thank you
m
@Ivan Pavlov it would look like this:
Copy code
``````val sortedMap = map
.entries
.sortedWith(compareByDescending<Map.Entry<String, Int>> { it.key }.thenBy { it.value })
.associate { it.key to it.value }``````
i
Personally I prefer associateBy version which doesn't create intermediate pairs for each entry too :)
m
``associateBy``
only allows you to specify the key, not the value.
i
No, there is overload which accepts both keySelector and valueTransform
m
Ah yeah, you’re right 🙂