Kotlin 前置元素
Kotlin prepend element
我正在寻找 Kotlin 的替代品:
(cons 1 '(2 3))
口齿不清或
1 : [2, 3]
在 haskell 或
1 :: List(2, 3)
在 Scala 中,
(所有结果都像 [1, 2, 3])
所以我可以将一个元素添加到 List<T>
(或您可以提供的任何其他列表)中。
如果可以提供 O(1) head
和 tail
Kotlin 替代方案也很好(我只找到了 first()
)
我不太确定你想做什么,所以请尝试以下操作之一。
变异列表:
val list = mutableListOf(3, 2)
list.add(1)
处理不可变列表:
var list = listOf(3, 2)
list = list + 1
任何实现 Deque
的 class 都适合您,例如 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]
我认为最简单的是写:
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
更多信息:
为了尽可能接近 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 不可变 collections(不仅仅是我们目前拥有的 read-only)的努力。到目前为止,这个项目还处于非常早期的阶段(我在那里找不到支持高效的结构 prepend/head/tail)
简单,只需将要添加的元素包装在 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)
如果您出于某种原因经常在代码中这样做,请考虑添加扩展运算符方法,例如:
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)
}
}
这可以通过下面的扩展函数轻松完成
前置元素
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)
我正在寻找 Kotlin 的替代品:
(cons 1 '(2 3))
口齿不清或
1 : [2, 3]
在 haskell 或
1 :: List(2, 3)
在 Scala 中,
(所有结果都像 [1, 2, 3])
所以我可以将一个元素添加到 List<T>
(或您可以提供的任何其他列表)中。
如果可以提供 O(1) head
和 tail
Kotlin 替代方案也很好(我只找到了 first()
)
我不太确定你想做什么,所以请尝试以下操作之一。
变异列表:
val list = mutableListOf(3, 2)
list.add(1)
处理不可变列表:
var list = listOf(3, 2)
list = list + 1
任何实现 Deque
的 class 都适合您,例如 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]
我认为最简单的是写:
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
更多信息:
为了尽可能接近 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 不可变 collections(不仅仅是我们目前拥有的 read-only)的努力。到目前为止,这个项目还处于非常早期的阶段(我在那里找不到支持高效的结构 prepend/head/tail)
简单,只需将要添加的元素包装在 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)
如果您出于某种原因经常在代码中这样做,请考虑添加扩展运算符方法,例如:
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)
}
}
这可以通过下面的扩展函数轻松完成
前置元素
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)