Sort collection by multiple fields in Kotlin

Kotlin

Kotlin Problem Overview


Let's say I have a list of People which I need to sort by Age first and then by Name.

Coming from a C#-background, I can easily achieve this in said language by using LINQ:

var list=new List<Person>();
list.Add(new Person(25, "Tom"));
list.Add(new Person(25, "Dave"));
list.Add(new Person(20, "Kate"));
list.Add(new Person(20, "Alice"));

//will produce: Alice, Kate, Dave, Tom
var sortedList=list.OrderBy(person => person.Age).ThenBy(person => person.Name).ToList(); 

How does one accomplish this using Kotlin?

This is what I tried (it's obviously wrong since the output of the first "sortedBy" clause gets overridden by the second one which results in a list sorted by Name only)

val sortedList = ArrayList(list.sortedBy { it.age }.sortedBy { it.name })) //wrong

Kotlin Solutions


Solution 1 - Kotlin

sortedWith + compareBy (taking a vararg of lambdas) do the trick:

val sortedList = list.sortedWith(compareBy({ it.age }, { it.name }))

You can also use the somewhat more succinct callable reference syntax:

val sortedList = list.sortedWith(compareBy(Person::age, Person::name))

Solution 2 - Kotlin

Use sortedWith to sort a list with Comparator.

You can then construct a comparator using several ways:

  • compareBy, thenBy construct the comparator in a chain of calls:

      list.sortedWith(compareBy<Person> { it.age }.thenBy { it.name }.thenBy { it.address })
    
  • compareBy has an overload which takes multiple functions:

      list.sortedWith(compareBy({ it.age }, { it.name }, { it.address }))
    

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFire095View Question on Stackoverflow
Solution 1 - KotlinAlexander UdalovView Answer on Stackoverflow
Solution 2 - KotlinhotkeyView Answer on Stackoverflow