Deconstruct with List<Int> in Kotlin

How does one deconstruct a List passed into a Kotlin function?

Problem:

Rather than passing a complex list of parameters to a function, I wanted to pass in a List and deconstruct it in the function body. The code below does not work, so I reverted to extracting each variable (Simplified code example below) – recommendations?

val (h1, m1, s1, h2, m2, s2) = timeData

Question:

What is the correct way to deconstruct the timeData into a component set of values?

Simplified Code Example:

import java.util.Scanner

const val HOURS = 3600
const val SECONDS = 60

fun secondsBetweenTwoMoments(timeData: List<Int>): Int {
    require(timeData.size == 6) { "List must have exactly 6 elements" }
    val h1 = timeData[0]
    val m1 = timeData[1]
    val s1 = timeData[2]
    val h2 = timeData[3]
    val m2 = timeData[4]
    val s2 = timeData[5]

    // Convert moment 1 and 2 to seconds
    val seconds1 = h1 * HOURS + m1 * SECONDS + s1
    val seconds2 = h2 * HOURS + m2 * SECONDS + s2
    return seconds2 - seconds1
}

fun main() {
    val scanner = Scanner(System.`in`)
    val inputs = mutableListOf<Int>()
    repeat(6) {
        inputs.add(scanner.nextInt())
    }
    val seconds = secondsBetweenTwoMoments(inputs)
    println(seconds)
}

to summarise, "Sir, I came across an interesting piece of magic…" (Chuckle)

>Solution :

You have simply hit the limit of the number of destructuring operator functions the standard library has defined for a List. You can add one more, and then the destructuring code will work:

operator fun <T> List<T>.component6(): T = get(5)

As for why they only built in destructuring up to 5 elements, I think it’s because beyond that it’s getting to be a little bit fragile/unreadable to use and you might want to consider using a specialized data class instead of a List.

I’m not sure why you mention casting, since there is no casting occurring in your code.

Leave a Reply