XDR
XDR

Reputation: 4470

Kotlin: generate a Comparable#compareTo() function from the properties of a class

In Kotlin, is there any concise way to generate a Comparable#compareTo() function for an interface that just calls this.property1.compareTo(that.property1) for each property of the interface in declaration order? Obviously, every property of the interface implements Comparable.

For interface I, it looks like I can create a top-level val like:

private val COMPARATOR = compareBy<I>(
    {it.property1},
    {it.property2},
    {it.property3},
    ...
)

And return COMPARATOR.compare(this, other) from I#compareTo(I), but, is there any simpler way to do this?

Upvotes: 3

Views: 692

Answers (1)

s1m0nw1
s1m0nw1

Reputation: 81889

You can use reflection and some simple language features like so:

inline fun <reified T : Any> compareByAll(): Comparator<T> {
    val selector = T::class.memberProperties
        .map { { i: T -> it.get(i) as Comparable<*> } }
        .toTypedArray()
    return compareBy(*selector)
}

Used like this:

val testInput = listOf(I(1, 2, 3), I(1, 2, 4), I(1, 0, 4), I(2, 3, 4), I(0, 1, 2)
testInput.sortedWith(compareByAll()))

Note that this solution doesn't handle the case that a property is not Comparable.

Upvotes: 1

Related Questions