34

Let's say I have a list of Strings in Kotlin: stringList: MutableList<String>

Then it is is easy to sort such list in case insensitive order by doing this:

stringList.sortWith(String.CASE_INSENSITIVE_ORDER)

But how would I sort a list of objects in case insensitive order? For example: places: MutableList<Place>

Where Place is a simple class with 2 fields - name: String and id: Int, and I would like to sort these Places by the name field.

I tried to do something like this: places.sortedWith(compareBy { it.name }) but this solution doesn't take letter case into account.

Scott Newson
  • 2,745
  • 2
  • 24
  • 26
user2999943
  • 2,419
  • 3
  • 22
  • 34
  • You can use this reference link : https://beginnersbook.com/2013/12/java-arraylist-of-object-sort-example-comparable-and-comparator/ – ViramP Aug 28 '17 at 14:05

2 Answers2

61

It looks like compareBy might be able to take a Comparator as an argument, see the documentation here: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.comparisons/compare-by.html

Try:

places.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER, { it.name }))

or

places.sortWith(compareBy(String.CASE_INSENSITIVE_ORDER, Place::name))

to sort the list in place, or you can assign it to a new variable using

val newList = places.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, { it.name }))
Adam Burley
  • 5,551
  • 4
  • 51
  • 72
Scott Newson
  • 2,745
  • 2
  • 24
  • 26
  • Great answer. Thanks! – user2999943 Aug 28 '17 at 14:11
  • 6
    FYI `places.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.name })` works the same and is how a final lambda parameter is usually written. `places.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, Place::name))` could also be written. – ephemient Aug 28 '17 at 20:54
  • How to do this case insensitive order for two fields? So e.g first for it.name and then it.last name? – K.Os Sep 11 '18 at 19:38
  • @ephemient How to do this case insensitive order for two fields? So e.g first for it.name and then it.last name? – K.Os Sep 11 '18 at 19:40
  • @K.Os looks like compareBy can take a varargs of lambdas, see this answer: https://stackoverflow.com/a/37259451/346912 – Scott Newson Jan 23 '19 at 14:37
  • "Note that this Comparator does not take locale into account, and will result in an unsatisfactory ordering for certain locales." - from method description. ```toLowerCase()``` lets you pass in a Locale. – Ivan Feb 26 '20 at 06:09
  • I found out the hard way that [`sortedWith`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sorted-with.html) returns a new instance of the sorted array, while [`sortWith`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort-with.html) sorts the array in place. Given the lack of an assignment, that was deceiving in the original answer. – Abandoned Cart Jan 27 '23 at 11:37
  • Is there a way to do this when you want to sort descending rather than ascending? – Adam Burley Aug 03 '23 at 15:05
17

Sort Ascending - case insensitive:

myList.sortedBy { it.name?.toLowerCase() }

Sort Descending - case insensitive:

myList.sortedByDescending { it.name?.toLowerCase() }
Ivo Stoyanov
  • 16,256
  • 8
  • 62
  • 65