Hi Guys! is there a more clean-kotlin-way to writ...
# getting-started
a
Hi Guys! is there a more clean-kotlin-way to write this code:
Copy code
if (v1 == null && v2 == null) {
            return 0
        }
        if (v1 != null && v2 == null) {
            return 1
        }
        if (v1 == null && v2 != null) {
            return -1
        }
d
arturro: Is that in a Comparator?
a
yes
It looks like this:
Copy code
override fun compare(o1: T, o2: T): Int {
        val property = o1.javaClass.kotlin.declaredMemberProperties.first { it -> it.name == propertyName }

        val v1 = property.get(o1) as? Comparable<Any>
        val v2 = property.get(o2) as? Comparable<Any>

        if (v1 == null && v2 == null) {
            return 0
        }
        if (v1 != null && v2 == null) {
            return 1
        }
        if (v1 == null && v2 != null) {
            return -1
        }
        return v1!!.compareTo(v2!!)
    }
d
You could just do
val c = compareBy(MyClass::property)
a
I dont know the property
I know it only at runtime, as a string name
d
Then you look it up using reflection and then pass it to
compareBy
.
And then you can use
nullsLast
resp.
nullsFirst
to allow nulls.
a
I am not sure how to do this. Now I have:
Copy code
fun <T : Any> List<T>.sortByProperty(propertyName: String, asc: Boolean = true) : List<T> {
    val field = ???
    return this.sortedBy { field }
}
But it does'n compile.
d
T
would have to be reified so you can get it's class. Then you can use T::class to look up the property
propertyName
should really not be a string though..
c
Do not use reflection in a comparator
a
I have to 🙂
c
Then at least don't do so for every call of
compare
a
Now I have something like this:
Copy code
inline fun <reified T : Any> List<T>.sortByPropertyName(propertyName: String) : List<T> {
    val prop = T::class.declaredMemberProperties.first { it.name == propertyName }
    return this.sortedBy { prop }
}
But it doesn't compile, the error is:
Copy code
Error:(11, 17) Kotlin: Type parameter bound for R in inline fun <T, R : Comparable<R>> Iterable<T>.sortedBy(crossinline selector: (T) -> R?): List<T>
 is not satisfied: inferred type KProperty1<T, *> is not a subtype of Comparable<KProperty1<T, *>>
Any suggestion how to fix it are welcome 🙂
c
@artur
prop
itself does not implement
Comparable
, you need code in there that can be mapped by the compiler to a
Comparable
e.g.
return this.sortedBy { -1 }
(obviously not what you want but you get the idea)
a
Thks Cédric!