Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert comparator to lambda in Kotlin

Tags:

lambda

kotlin

There is a code snipt in my Kotlin code:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap(object : Comparator<Double> {
            override fun compare(p0: Double, p1: Double): Int {
                return (p1-p0).compareTo(0)
            }
        })

It worked just fine. However the IDE keeps suggesting me to convert that Comparator object to a lambda, and I did just that:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap {x, y -> (y-x).compareTo(0)}

This shold work. However, it can't be compiled:

Error:(32, 14) Kotlin: Type inference failed: fun <K, V> Map<out K, V>.toSortedMap(comparator: Comparator<in K>): SortedMap<K, V> cannot be applied to receiver: Map<Double, Double>  arguments: ((Double, Double) -> Int)

Any ideas what went wrong? Thanks in advance.

like image 846
Jue Wang Avatar asked Jun 23 '17 12:06

Jue Wang


People also ask

What is lambda comparator?

A lambda expression used with any functional interface and Comparator is a functional interface. The Comparator interface has used when sorting a collection of objects compared with each other. In the below example, we can sort the employee list by name using the Comparator interface.

What is trailing lambda in Kotlin?

Trailing lambda syntax. First line from Listing 7.27, calling out the first argument (20.0) and the second argument (the lambda). val withFiveDollarsOff = calculateTotal ( 20.0 ) { price - > price - 5.0 } In Kotlin, writing the lambda outside of the parentheses like this is called trailing lambda syntax.

What is Kotlin comparator?

Compares its two arguments for order. Returns zero if the arguments are equal, a negative number if the first argument is less than the second, or a positive number if the first argument is greater than the second.


1 Answers

Try this way:

val dataMap = sensoryDataUsage.groupBy { it }
        .mapValues { it.value.count().toDouble()/count }
        .mapKeys { println(it.key); it.key.toDouble()/max }
        .toSortedMap(Comparator<Double> { p0, p1 -> (p1-p0).compareTo(0) })

You have a lot of answers with working code, but I'll try to explain why didn't your code work. Take a look on this lambda:

p0, p1 -> (p1-p0).compareTo(0)

It would generate a method which one returns type specified inside of the last called method, in our case - compareTo. In another words - this lambda would return integer. But your code needs a double, so you should specify type of returning value as Double. Now when you got a reasons feel free to use any of suggested solutions, which fits you better.

like image 148
A. Shevchuk Avatar answered Oct 30 '22 14:10

A. Shevchuk