如何将Kotlin列表破坏为子列表?

时间:2018-01-12 18:12:02

标签: list kotlin

如何将Kotlin中的列表分成两个子列表?目前我这样做:

val (first, rest) = listOf("one", "two", "three")

但这样做,首先是“一个”,休息是“两个”。我希望它们是first =["first"]rest = ["two", "three"]

使用这种“析构函数”语法甚至可以实现吗?

4 个答案:

答案 0 :(得分:8)

Destructuring转换为在对象上调用component1component2等运算符函数。在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 headtail,以便您可以这样做:

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),以防止每次都复制列表。