Home > Back-end >  kotlin compareBy using IntArray, how do I get the 'a' and 'b' fields?
kotlin compareBy using IntArray, how do I get the 'a' and 'b' fields?

Time:11-26

new to kotlin and struggle with the syntax of compareBy and its lambda to get the 'a' and 'b' parameters for a custom compare:

public inline fun <T> compareBy(crossinline selector: (T) -> Comparable<*>?): Comparator<T> =
    Comparator { a, b -> compareValuesBy(a, b, selector) }

Basically I want to compare 2d points that are stored as IntArray(x,y) but don't know how to access the a and b elements of the declaration. Here where I am stuck:

val compareByDistance: Comparator<IntArray> = compareBy {
    // b - a to origin = (bx2 - 0)^2 - (by2 - 0)^2 -> no need square root
    val distance = -1
    distance
}

val points = PriorityQueue<IntArray>(compareByDistance)
points.add(intArrayOf(1, 2))
points.add(intArrayOf(2, 3))

when I run the debugger I see the 'a' and 'b' parameters, but I have to idea how to access them.

enter image description here

If I do:

val k = it.first()

it does not give k = a = [2,3] just k =2, but still I can't access b.

What is the correct syntax for the lambda? I looked in this thread by did not help:

https://www.bezkoder.com/kotlin-priority-queue/

thank you.

CodePudding user response:

Try this.

   val compareByDistance = Comparator<IntArray> { a:IntArray, b:IntArray ->
            // Return -1 ,  1 ,0 - Based on your Formula
            0
        }

Here in your code , when you see compareBy will be accepting lambda of type Comparable<T> which has only one parameter. It will only return default Comparator.

The solution is to create object for Comparator Interface like above . In which compare has two arguments.

CodePudding user response:

I’m assuming from the formula you have in your code comment that you are wanting to compare your points by their distance from the origin (0, 0).

The compareBy lambda has a single parameter since you use it to convert each individual IntArray into a number that will be used to compare it to other IntArrays.

When a lambda has a single parameter and you leave it blank like in your code above, it has the implicit name it, so you could use it[0] and it[1] for a and b. But you can name it using a destructuring declaration to conveniently get named a and b variables.

val compareByDistance: Comparator<IntArray> = compareBy { (a, b) ->
    a * a   b * b
}
  • Related