如何将Kotlin中的列表分成两个子列表?目前我这样做:
val (first, rest) = listOf("one", "two", "three")
但这样做,首先是“一个”,休息是“两个”。我希望它们是first =["first"]
和rest = ["two", "three"]
。
使用这种“析构函数”语法甚至可以实现吗?
答案 0 :(得分:8)
Destructuring转换为在对象上调用component1
,component2
等运算符函数。在List
的情况下,这些被定义为extensions in the standard library,并分别返回第N个元素。
您可以定义自己的扩展程序扩展名,根据需要拆分列表并返回Pair
,然后可以对其进行解构:
fun <T> List<T>.split() = Pair(take(1), drop(1))
这可以这样使用:
val (first, rest) = listOf("one", "two", "three").split()
println(first) // [one]
println(rest) // [two, three]
或许将它命名为比split
更好的东西,但这很聪明。
答案 1 :(得分:5)
您还可以定义自己的组件功能:
operator fun <T> List<T>.component2(): List<T> = this.drop(1)
然后按预期工作:
val (head, rest) = listOf("one", "two", "three")
println(head) // "one"
println(rest) // ["two", "three"]
答案 2 :(得分:2)
可以通过创建component2
运算符作为扩展方法manyally:
operator fun <T> List<T>.component2(): List<T> = drop(1)
fun destrcutList() {
val (first: String, second: List<String>) = listOf("1", "2", "3")
}
您只需为component2
创建扩展方法,component1
将像以前一样使用。
类型可以省略:
fun destrcutList() {
val (first, second) = listOf("1", "2", "3")
println(second[0]) // prints "2"
}
一个重要注意事项:如果您在另一个包中声明扩展方法,则必须手动导入功能:
import your.awesome.package.component2
答案 3 :(得分:1)
这可以使用extension function来实现。这是我的看法:
val <T> List<T>.tail: List<T>
get() = subList(1, size)
val <T> List<T>.head: T
get() = first()
fun <T> List<T>.headTail() = Pair(head, tail)
首先我要定义extensions properties head
和tail
,以便您可以这样做:
val list = listOf("one", "two", "three")
println(list.head) // "one"
println(list.tail) // ["two", "three"]
(如果你不喜欢扩展属性,你可以简单地内联headTail
函数中的代码)
最后,headTail
函数可以像这样使用:
val (head, tail) = listOf("one", "two", "three").headTail()
println(head) // "one"
println(tail) // ["two", "three"]
请注意,我使用subList
代替{em> tail 而不是drop(1)
,以防止每次都复制列表。