Kotlin前置元素

时间:2017-03-19 21:00:20

标签: list insert kotlin prepend cons

我正在寻找Kotlin替代方案:
    {1}}在lisp或中     (cons 1 '(2 3))在haskell或
中     scala 1 : [2, 3]
(所有结果都像[1,2,3])
所以我可以将一个元素添加到1 :: List(2, 3)(或您可以提供的任何其他列表)。

如果可以提供O(1)List<T>head Kotlin替代品(我发现只有tail),那也没关系

7 个答案:

答案 0 :(得分:8)

我认为最简单的是写:

var list = listOf(2,3)
println(list) // [2, 3]
list = listOf(1) + list
println(list) // [1, 2, 3]

没有特定的tail实现,但您可以调用.drop(1)来获得相同的内容。您可以通过编写以下扩展属性来使此head\tail更通用:

val <T> List<T>.tail: List<T>
  get() = drop(1)

val <T> List<T>.head: T
  get() = first()

然后:

val list = listOf(1, 2, 3)
val head = list.head
val tail = list.tail

更多信息:Kotlin List tail function

答案 1 :(得分:5)

任何实现Deque的类都适合您,例如LinkedList

val linkedList = LinkedList(listOf(2, 3))
linkedList.push(1)
println(linkedList) // [1, 2, 3]

在许多地方通过构造函数LinkedList(listOf(2, 3))创建列表可能很烦人,所以随意编写工厂方法:

fun <T> linkedListOf(vararg elements: T): LinkedList<T> {
    return LinkedList<T>(elements.toList())
}

// Usage:
val list = linkedListOf(2, 3)
list.push(1)
println(list) // [1, 2, 3]

答案 2 :(得分:2)

简单,只需将元素包装在List前面,然后使用+运算符(或List.plus())将两个Lists串联起来即可:

val list1 = listOf(2, 3)        // [2, 3]
val list2 = listOf(1) + list1   // [1, 2, 3]

关于第二个问题,在Kotlin 1.2中:

List.first()
List.last()

都是O(1)

答案 3 :(得分:0)

尽可能接近Lisp考虑使用不可变链表。

您可以使用pcollections

val list = ConsPStack.from(listOf(2, 3))
val newList = list + 1
println(list)  // [2, 3]
println(newList) // [1, 2, 3]

目:

list.first() // 1
list[0] // 1

(不幸的是这件事需要一次分配)

尾巴:

list - 0 // [2, 3]
list.subList(1) // [2, 3]  
看起来很丑陋。

希望在kotlinx.collections.immutable准备就绪后,我们会获得更好的API。它是创建标准Kotlin不可变集合(不仅仅是我们目前拥有的只读集合)的努力。截至目前,该项目仍处于初期阶段(我无法找到支持高效前置/头/尾的结构)

答案 4 :(得分:0)

如果出于某种原因经常在代码中执行此操作,请考虑添加扩展运算符方法,例如:

operator fun <T> T.plus(tail: List<T>): List<T> {
    val list = ArrayList<T>(1 + tail.size)

    list.add(this)
    list.addAll(tail)

    return list
}

然后您的代码可以像Scala一样工作:1 + listOf(2, 3)

另一种实现相同行为的方法,虽然较短,但会牺牲一些内存:

operator fun <T> T.plus(tail: List<T>): List<T> {
    return mutableListOf(this).apply {
        addAll(tail)
    }
}

答案 5 :(得分:0)

这可以通过以下扩展功能轻松完成

待处理元素

fun <T> MutableList<T>.prepend(element: T) {
    add(0, element)
}

待处理列表

fun <T> MutableList<T>.prependAll(elements: List<T>) {
    addAll(0, elements)
}

答案 6 :(得分:-3)

我不完全确定你想做什么,所以请尝试以下方法之一。

变异名单:

{{1}}

复制不可变列表:

{{1}}