Элемент предварительного ввода Kotlin
Я ищу альтернативу Kotlin для:
(cons 1 '(2 3))
в lisp или
1 : [2, 3]
в haskell или
1 :: List(2, 3)
в scala,
(которые все приводят к sth, как [1, 2, 3])
поэтому я могу добавить элемент в List<T>
(или любой другой список, который вы можете предложить).
Это также будет хорошо, если вы можете предоставить варианты O (1) head
и tail
Kotlin (я нашел только first()
)
Ответы
Ответ 1
Любой класс, который реализует Deque
, подходит вам, например LinkedList
:
val linkedList = LinkedList(listOf(2, 3))
linkedList.push(1)
println(linkedList) // [1, 2, 3]
Создание списков через конструктор LinkedList(listOf(2, 3))
во многих местах может быть раздражающим, поэтому не стесняйтесь писать метод factory:
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
Я думаю, что проще всего написать:
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
Ответ 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)
Ответ 4
Чтобы как можно ближе к 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]
Выглядит довольно уродливо.
Надеемся, что мы получим лучший API, когда kotlinx.collections.immutable будет готов. Это попытка создать стандартные неизменные коллекции Kotlin (а не только доступные для чтения, которые у нас есть). На данный момент этот проект все еще находится на очень ранней стадии (мне не удалось найти структуру, поддерживающую эффективный preend/head/tail)
Ответ 5
Если вы по какой-то причине часто делаете это в своем коде, рассмотрите возможность добавления метода оператора расширения, такого как:
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)
}
}
Ответ 6
Это можно легко сделать с помощью расширенных функций, как показано ниже
Предопределяющий элемент
fun <T> MutableList<T>.prepend(element: T) {
add(0, element)
}
Предварительный список
fun <T> MutableList<T>.prependAll(elements: List<T>) {
addAll(0, elements)
}
Ответ 7
Я не совсем уверен, что вы хотите сделать, поэтому, пожалуйста, попробуйте одно из следующих.
Мутирующий список:
val list = mutableListOf(3, 2)
list.add(1)
Использование неизменяемого списка:
var list = listOf(3, 2)
list = list + 1