1

I know it's possible to sort a list of person by a property using following syntax:

persons = persons.sortedBy { person: Person-> person.name }

Now i want to write a sort function which accepts the property by which i want the list to be sorted by as an parameter.

In JavaScript i would write something like this:

fun sort(property: String) { 
        persons = persons.sortedBy { person: Person-> person[property]} 
}

But i cannot write "person[property]" in Kotlin.

So how can i achieve such a sorting function in Kotlin?

2 Answers 2

4

Now i want to write a sort function which accepts the property by which i want the list to be sorted by as an parameter.

Let's hope that by "the property", you can settle for something like a function reference:

data class Person(val name: String, val age: Int)
  
var people = listOf(Person("Jane Doe", 25), Person("John Smith", 24), Person("Jen Jones", 37))

fun <R: Comparable<R>> sort(selector: (Person) -> R) {
  people = people.sortedBy(selector)
}

fun main() {
  println(people)
  sort(Person::name)
  println(people)
}

I could also use sort(Person::age) if I wanted to sort by age.

If your pseudocode is more literal, and you want a String parameter for the property name, you should start by asking yourself "why?". But, if you feel that you have a legitimate reason to use a String, one approach would be:

data class Person(val name: String, val age: Int)
  
var people = listOf(Person("Jane Doe", 25), Person("John Smith", 24), Person("Jen Jones", 37))

fun sort(property: String) {
  people = when(property) {
    "name" -> people.sortedBy(Person::name)
    "age" -> people.sortedBy(Person::age)
    else -> throw IllegalArgumentException("and this is why you should not be doing this")
  }
}

fun main() {
  println(people)
  sort("name")
  println(people)
}
Sign up to request clarification or add additional context in comments.

2 Comments

There is also a description for all possible variants. It is also possible to sort by several fields.
Yes, a selector function is the standard way of doing this; you can see many examples in the standard library. As you demonstrate, providing a function name is awkward and restrictive, as well as being a lot less flexible. (You could also do something with reflection, but that's usually a very bad idea.)
0
class CustomObject(val customProperty: String, val value:Int)

 val list = ArrayList<CustomObject>()
        list.add(CustomObject("Z",5))
        list.add(CustomObject("A",4))
        list.add(CustomObject("B",1))
        list.add(CustomObject("X",6))
        list.add(CustomObject("Aa",7))

        var alphabeticallySortedList = list.sortedWith(compareBy { it.customProperty })
        var numberWiseSortedList = list.sortedWith(compareBy { it.value })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.