Список[A: A]
Двусвязный список.
(Следующее взято из Википедии.)
Двусвязный список — это структура данных, состоящая из набора последовательно связанных записей, называемых узлами. (Реализовано в Ponylang через класс collections.ListNode.) Каждый узел содержит четыре поля: два поля ссылки (ссылки на предыдущий и следующий узел в последовательности узлов), одно поле данных и ссылку на список, в котором он находится. Двусвязный список можно представить как два односвязных списка, сформированных из тех же элементов данных, но в обратном порядке.
Как вы ожидаете, предоставляются функции для выполнения всех общих операций со списком, таких как создание, обход, добавление и удаление узлов, итерация, отображение, фильтрация и т. д.
Пример программы
В списке много функций. Следующий код демонстрирует несколько распространенных примеров.
Он выводит:
A new empty list has 0 nodes. Adding one node to our empty list means it now has a size of 1. The first (index 0) node has the value: A single String A list created by appending our second single-node list onto our first has size: 2 The List nodes of our first list are now: A single String Another String Append *moves* the nodes from the second list so that now has 0 nodes. A list created from an array of three strings has size: 3 First Second Third Mapping over our three-node list produces a new list of size: 3 Each node-value in the resulting list is now far more exciting: First BOOM! Second BOOM! Third BOOM! Filtering our three-node list produces a new list of size: 2 Second BOOM! Third BOOM! The size of our first partitioned list (matches predicate): 1 The size of our second partitioned list (doesn't match predicate): 1 Our matching partition elements are: Second BOOM!
use "collections"
actor Main
new create(env:Env) =>
// Create a new empty List of type String
let my_list = List[String]()
env.out.print("A new empty list has " + my_list.size().string() + " nodes.") // 0
// Push a String literal onto our empty List
my_list.push("A single String")
env.out.print("Adding one node to our empty list means it now has a size of "
+ my_list.size().string() + ".") // 1
// Get the first element of our List
try env.out.print("The first (index 0) node has the value: "
+ my_list.index(0)?()?.string()) end // A single String
// Create a second List from a single String literal
let my_second_list = List[String].unit("Another String")
// Append the second List to the first
my_list.append_list(my_second_list)
env.out.print("A list created by appending our second single-node list onto our first has size: "
+ my_list.size().string()) // 2
env.out.print("The List nodes of our first list are now:")
for n in my_list.values() do
env.out.print("\t" + n.string())
end
// NOTE: this _moves_ the elements so second_list consequently ends up empty
env.out.print("Append *moves* the nodes from the second list so that now has "
+ my_second_list.size().string() + " nodes.") // 0
// Create a third List from a Seq(ence)
// (In this case a literal array of Strings)
let my_third_list = List[String].from(["First"; "Second"; "Third"])
env.out.print("A list created from an array of three strings has size: "
+ my_third_list.size().string()) // 3
for n in my_third_list.values() do
env.out.print("\t" + n.string())
end
// Map over the third List, concatenating some "BOOM!'s" into a new List
let new_list = my_third_list.map[String]({ (n) => n + " BOOM!" })
env.out.print("Mapping over our three-node list produces a new list of size: "
+ new_list.size().string()) // 3
env.out.print("Each node-value in the resulting list is now far more exciting:")
for n in new_list.values() do
env.out.print("\t" + n.string())
end
// Filter the new list to extract 2 elements
let filtered_list = new_list.filter({ (n) => n.string().contains("d BOOM!") })
env.out.print("Filtering our three-node list produces a new list of size: "
+ filtered_list.size().string()) // 2
for n in filtered_list.values() do
env.out.print("\t" + n.string()) // Second BOOM!\nThird BOOM!
end
// Partition the filtered list
let partitioned_lists = filtered_list.partition({ (n) => n.string().contains("Second") })
env.out.print("The size of our first partitioned list (matches predicate): " + partitioned_lists._1.size().string()) // 1
env.out.print("The size of our second partitioned list (doesn't match predicate): " + partitioned_lists._2.size().string()) // 1
env.out.print("Our matching partition elements are:")
for n in partitioned_lists._1.values() do
env.out.print("\t" + n.string()) // Second BOOM!
end
class ref List[A: A] is Seq[A] ref
Реализует
- Последовательность[A] ссылка
Конструкторы
create
Ничего не делает, но совместим с последовательностью.
new ref create( len: USize val = 0) : List[A] ref^
Параметры
- len: USize значение = 0
Возвращает
- Список[A] ссылка^
unit
Создаёт новый список из элемента.
new ref unit( a: A) : List[A] ref^
Параметры
- a: A
Возвращает
- Список[A] ссылка^
from
Создает новый список из переданной последовательности.
new ref from( seq: Array[A^] ref) : List[A] ref^
Параметры
- seq: Массив[A^] ссылка
Возвращает
- Список[A] ссылка^
Публичные функции
reserve
Ничего не делает, но совместим с последовательностью.
fun ref reserve( len: USize val) : None val
Параметры
- len: USize значение
Возвращает
- None значение
размер
Возвращает количество элементов в списке.
fun box size() : USize val
Возвращает
- USize значение
apply
Получает i-й элемент, вызывая ошибку, если индекс вне диапазона.
fun box apply( i: USize val = 0) : this->A ?
Параметры
- i: USize значение = 0
Возвращает
- this->A ?
update
Изменяет i-й элемент, вызывая ошибку, если индекс вне диапазона. Возвращает предыдущее значение, которое может быть None, если узел был удален, но остался в списке.
fun ref update( i: USize val, value: A) : A^ ?
Параметры
- i: USize значение
- значение: A
Возвращает
- A^ ?
индекс
Получает i-й узел, вызывая ошибку, если индекс вне диапазона.
fun box index( i: USize val) : this->ListNode[A] ref ?
Параметры
- i: USize значение
Возвращает
- this->Узел[A] ссылка ?
удаление
Удаляет i-й узел, вызывая ошибку, если индекс вне диапазона. Удаленный узел возвращается.
fun ref remove( i: USize val) : ListNode[A] ref ?
Параметры
- i: USize значение
Возвращает
- Узел[A] ссылка ?
очистить
Очищает список.
fun ref clear() : None val
Возвращает
- None значение
голова
Получает начало списка.
fun box head() : this->ListNode[A] ref ?
Возвращает
- this->Узел[A] ссылка ?
хвост
Получает конец списка.
fun box tail() : this->ListNode[A] ref ?
Возвращает
- this->Узел[A] ссылка ?
добавить_в_начало_узел
Добавляет узел в начало списка.
fun ref prepend_node( node: ListNode[A] ref) : None val
Параметры
- узел: Узел[A] ссылка
Возвращает
- None значение
добавить_в_конец_узел
Добавляет узел в конец списка.
fun ref append_node( node: ListNode[A] ref) : None val
Параметры
- узел: Узел[A] ссылка
Возвращает
- None значение
добавить_список
Удаляет все узлы из того и добавляет их в этот.
fun ref append_list( that: List[A] ref) : None val
Параметры
- that: Список[A] ссылка
Возвращает
- None значение
вставить_список
Удаляет все узлы из того и вставляет их в начало этого.
fun ref prepend_list( that: List[A] ref) : None val
Параметры
- that: Список[A] ссылка
Возвращает
- None значение
push
Добавляет значение в конец списка.
fun ref push( a: A) : None val
Параметры
- a: A
Возвращает
- None значение
pop
Удаляет значение из конца списка.
fun ref pop() : A^ ?
Возвращает
- A^ ?
unshift
Добавляет значение в начало списка.
fun ref unshift( a: A) : None val
Параметры
- a: A
Возвращает
- None значение
shift
Удаляет значение из начала списка.
fun ref shift() : A^ ?
Возвращает
- A^ ?
append
Добавляет len элементов из последовательности, начиная с заданного смещения.
fun ref append( seq: (ReadSeq[A] box & ReadElement[A^] box), offset: USize val = 0, len: USize val = call) : None val
Параметры
- seq: (Последовательность[A] коробка & Читаемый элемент[A^] коробка)
- смещение: USize значение = 0
- len: USize значение = вызов
Возвращает
- None значение
concat
Добавляет len элементов, полученных из итератора, в конец списка, начиная с заданного смещения.
fun ref concat( iter: Iterator[A^] ref, offset: USize val = 0, len: USize val = call) : None val
Параметры
Возвращает
- None значение
обрезать
Обрезает список до заданной длины, удаляя лишние элементы. Если список уже меньше len, ничего не делает.
fun ref truncate( len: USize val) : None val
Параметры
- len: USize значение
Возвращает
- None значение
клонировать
Клонирует список.
fun box clone() : List[this->A!] ref^
Возвращает
- Список[this->A!] ссылка^
map[B: B]
Создает новый список, применяя функцию к каждому элементу списка.
fun box map[B: B](
f: {(this->A!): B^}[A, B] box)
: List[B] ref^
Параметры
- f: {(this->A!): B^}[A, B] коробка
Возвращает
- Список[B] ссылка^
flat_map[B: B]
Создаёт новый список, применяя функцию к каждому элементу списка и используя элементы полученных списков.
fun box flat_map[B: B](
f: {(this->A!): List[B]}[A, B] box)
: List[B] ref^
Параметры
- f: {(this->A!): Список[B]}[A, B] коробка
Возвращает
- Список[B] ссылка^
фильтр
Создаёт новый список с элементами, удовлетворяющими заданному предикату.
fun box filter(
f: {(this->A!): Bool}[A] box)
: List[this->A!] ref^
Параметры
- f: {(this->A!): Bool}[A] box
Возвращает
- Список[this->A!] ref^
fold[B: B]
Выполняет сжатие элементов списка с помощью заданной функции.
fun box fold[B: B](
f: {(B!, this->A!): B^}[A, B] box,
acc: B)
: B
Параметры
- f: {(B!, this->A!): B^}[A, B] box
- acc: B
Возвращает
- B
every
Возвращает true, если все элементы удовлетворяют заданному предикату, иначе false.
fun box every(
f: {(this->A!): Bool}[A] box)
: Bool val
Параметры
- f: {(this->A!): Bool}[A] box
Возвращает
- Булево значение
exists
Возвращает true, если хотя бы один элемент удовлетворяет заданному предикату, иначе false.
fun box exists(
f: {(this->A!): Bool}[A] box)
: Bool val
Параметры
- f: {(this->A!): Bool}[A] box
Возвращает
- Булево значение
partition
Создаёт пару списков, первый из которых состоит из элементов, удовлетворяющих заданному предикату, а второй — из элементов, не удовлетворяющих ему.
fun box partition(
f: {(this->A!): Bool}[A] box)
: (List[this->A!] ref^ , List[this->A!] ref^)
Параметры
- f: {(this->A!): Bool}[A] box
Возвращает
drop
Создаёт список, отбрасывая первые n элементов.
fun box drop( n: USize val) : List[this->A!] ref^
Параметры
- n: USize значение
Возвращает
- Список[this->A!] ref^
take
Создаёт список из первых n элементов.
fun box take( n: USize val) : List[this->A!] ref
Параметры
- n: USize значение
Возвращает
- Список[this->A!] ref
take_while
Создаёт список элементов, удовлетворяющих заданному предикату, пока один из них не перестаёт удовлетворять ему.
fun box take_while(
f: {(this->A!): Bool}[A] box)
: List[this->A!] ref^
Параметры
- f: {(this->A!): Bool}[A] box
Возвращает
- Список[this->A!] ref^
reverse
Создаёт новый список, меняя местами элементы в списке.
fun box reverse() : List[this->A!] ref^
Возвращает
- Список[this->A!] ref^
contains[optional B: (A & HasEq[A!] #read)]
Возвращает true, если список содержит указанный элемент, иначе false.
fun box contains[optional B: (A & HasEq[A!] #read)]( a: box->B) : Bool val
Параметры
- a: box->B
Возвращает
- Булево значение
nodes
Возвращает итератор по узлам в списке.
fun box nodes() : ListNodes[A, this->ListNode[A] ref] ref^
Возвращает
rnodes
Возвращает итератор по узлам в списке.
fun box rnodes() : ListNodes[A, this->ListNode[A] ref] ref^
Возвращает
values
Возвращает итератор по значениям в списке.
fun box values() : ListValues[A, this->ListNode[A] ref] ref^
Возвращает
- ListValues[A, this->ListNode[A] ref] ref^
rvalues
Возвращает итератор по значениям в списке.
fun box rvalues() : ListValues[A, this->ListNode[A] ref] ref^
Возвращает
- ListValues[A, this->ListNode[A] ref] ref^
© 2016-2020, The Pony Developers
© 2014-2015, Causality Ltd.
Licensed under the BSD 2-Clause License.
https://stdlib.ponylang.io/collections-List