Kotlin 前置元素



我正在寻找 Kotlin 的替代品:
(cons 1 '(2 3)) Lisp 或
1 : [2, 3]在哈斯克尔或
1 :: List(2, 3)在斯卡拉
(都会导致 sth 像 [1, 2, 3](
所以我可以在List<T>(或您可以提供的任何其他列表(前面附加一个元素。

如果可以提供 O(1( headtail Kotlin 替代品也很好(我只找到了 first() 个(

我认为最简单的方法是写:

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

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

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 列表尾函数

任何实现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]

很简单,只需将元素包装为前缀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(

这可以通过如下扩展函数轻松完成

前置元素

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

前置列表

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

元素插入到列表中指定索引处。

abstract fun add(index: Int, element: E)

因此答案是

list.add(0,element)

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

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)
    }
}

为了尽可能接近 Lisp,请考虑使用不可变的链表。

您可以使用收藏集

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 不可变集合(不仅仅是我们目前拥有的只读集合(的努力。到目前为止,这个项目仍处于非常早期的阶段(我无法在那里找到支持高效前置/头/尾的结构(

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

变异列表:

val list = mutableListOf(3, 2)
list.add(1)

处理不可变列表:

var list = listOf(3, 2)
list = list + 1

相关内容

  • 没有找到相关文章

最新更新