Reputation: 4470
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
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