https://kotlinlang.org logo
#getting-started
Title
# getting-started
p

Pihentagy

03/16/2023, 10:17 AM
Hi, is there a more compact way to destructure the four coordinates?
j

Johann Pardanaud

03/16/2023, 10:18 AM
Copy code
val (upper, left) = boundingBox.upperLeft
val (lower, right) = boundingBox.lowerRight
👍 1
y

Youssef Shoaib [MOD]

03/16/2023, 10:19 AM
inside of BoundingBox you could define
component1-4
and have them return the individual BigDecimals
👍 1
j

Johann Pardanaud

03/16/2023, 10:19 AM
I don’t think there is any nested destructuring in kotlin
😢 1
y

Youssef Shoaib [MOD]

03/16/2023, 10:21 AM
Copy code
data class BoundingBox(val upperLeft: Coord, val lowerRight: Coord) {
    operator fun component1() = upperLeft.lat
    operator fun component2() = upperLeft.lng
    operator fun component3() = lowerRight.lat
    operator fun component4() = lowerRight.lng
}
Edit: this throws an error because
component1
and 2 are overloaded
p

Pihentagy

03/16/2023, 10:23 AM
Yes, thanks, looked for nested destructuring, but if there is nothing like that I won't search for it in vain.
w

wbertan

03/16/2023, 10:35 AM
It seems Kotlin only supports Tuple up to 3. So you could create some "helpers" to support Tuples of 4:
Copy code
data class NTuple2<T1, T2>(val t1: T1, val t2: T2)

data class NTuple3<T1, T2, T3>(val t1: T1, val t2: T2, val t3: T3)

data class NTuple4<T1, T2, T3, T4>(val t1: T1, val t2: T2, val t3: T3, val t4: T4)

infix fun <T1, T2> T1.then(t2: T2): NTuple2<T1, T2> {
    return NTuple2(this, t2)
}

infix fun <T1, T2, T3> NTuple2<T1, T2>.then(t3: T3): NTuple3<T1, T2, T3> {
    return NTuple3(this.t1, this.t2, t3)
}

infix fun <T1, T2, T3, T4> NTuple3<T1, T2, T3>.then(t4: T4): NTuple4<T1, T2, T3, T4> {
    return NTuple4(this.t1, this.t2, this.t3, t4)
}
And its constructors. Then you could do something like:
Copy code
val (upper, left, lower, right) =
        boundingBox.upperLeft.lat then
            boundingBox.upperLeft.lng then
            boundingBox.lowerRight.lat then
            boundingBox.lowerRight.lng
🤔 I think it could work
p

phldavies

03/16/2023, 10:47 AM
You can use an inline class to wrap the data class and expose alternative component operators as required:
Copy code
data class Coord(val latitude: Double, val longitude: Double)
data class Area(val upperLeft: Coord, val lowerRight: Coord)

@JvmInline
value class AreaCoordinates(val area: Area) {
    operator fun component1() = area.upperLeft.latitude
    operator fun component2() = area.upperLeft.longitude
    operator fun component3() = area.lowerRight.latitude
    operator fun component4() = area.lowerRight.longitude
}

fun Area.coordinates() = AreaCoordinates(this)

fun main() {
    val (a, b, c, d) = Area(Coord(12.34, 56.78), Coord(-56.78, -123.4)).coordinates()
    println("$a,$b,$c,$d")
}
allo love 1
🙌 1
👏 1
k

Klitos Kyriacou

03/16/2023, 2:30 PM
Is it conventional to order the four edges in the specific sequence (upper, left, lower, right)? If so, then it's ok to use componentN. Otherwise, I would stick to property names instead.
p

phldavies

03/16/2023, 4:25 PM
There is no standardised convention I'm aware of, but generally it's the order one would expect. Also if kotlin supported nested destructuring, then you would have the same order with
((a, b), (c, d))
4 Views