Hi, is there a more compact way to destructure the...
# getting-started
p
Hi, is there a more compact way to destructure the four coordinates?
j
Copy code
val (upper, left) = boundingBox.upperLeft
val (lower, right) = boundingBox.lowerRight
👍 1
y
inside of BoundingBox you could define
component1-4
and have them return the individual BigDecimals
👍 1
j
I don’t think there is any nested destructuring in kotlin
😢 1
y
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
Yes, thanks, looked for nested destructuring, but if there is nothing like that I won't search for it in vain.
w
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
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
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
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))