This question is kinda all over the place (stdlib design, code golf), so apologies in advance.
We have a list of size >= 2 and we’d like to peel off the first two values into separate variables and create a new list from the remaining values, essentially something like this:
val list = listOf(1, 2, 3)
val first = list[0]
val second = list[1]
val rest = list.drop(2)
(What we actually did was introduce a List.splitAt(idx: Int): Pair<List, List> extension method:)
val list = listOf(1, 2, 3)
val (meta, rest) = list.splitAt(2)
val (first, second) = meta
But this isn’t that much better.
What we’d really like is this:
val list = listOf(1, 2, 3)
val ((first, second), *rest) = list
but this isn’t possible right now in 1.1.
What are people’s thoughts? Is there a cleaner idiomatic way to do what we’re doing?
But the spread operator is not an option, since list has finite amount of componentN() and using an interface (like Iterable) for syntactical purposes is out of the question IMO.
And then you’d have to decide what kind of collection the rest variable would collect the results in.
data class Person(val name: String, val age: Int)
//...
val p = Person("Fred", 45)
val (name) = p
println(name) // Fred
So it appears that the destructuring syntax, starting from component1, simply extracts as many components as you have variables and (if there are any) leaves the rest.
Using val (first, second) = list when the list is >2 in length does work, and might be what we end up doing, but still seems potentially misleading to the next reader.