Spec-Zone.ru › Nim

std/sequtils

ИсточникРедактировать

Хотя в имени этого модуля есть seq, он реализует операции не только для типа seq, но и для трёх встроенных типов контейнеров под openArray зонтиком:

  • последовательности
  • строки
  • массивы

Модуль system определяет несколько общих функций, таких как:

  • newSeq[T] для создания новых последовательностей типа T
  • @ для преобразования массивов и строк в последовательности
  • add для добавления новых элементов в строки и последовательности
  • & для конкатенации строк и seq
  • in (псевдоним для contains) и notin для проверки, находится ли элемент в контейнере

Этот модуль опирается на это, предоставляя дополнительную функциональность в виде процедур, итераторов и шаблонов, вдохновлённых языками функционального программирования.

Для функционального стиля программирования у вас есть различные варианты:

  • макрос sugar.collect
  • передача анонимной процедуры анонимной процедуры
  • импорт модуля sugar и использование макроса =>
  • использование шаблонов ...It (mapIt, filterIt и др.)

Цепочечное вызов функций возможно благодаря синтаксису вызова методов.

Пример:

import std/sequtils
import std/sugar

# Creating a sequence from 1 to 10, multiplying each member by 2,
# keeping only the members which are not divisible by 6.
let
  foo = toSeq(1..10).map(x => x * 2).filter(x => x mod 6 != 0)
  bar = toSeq(1..10).mapIt(it * 2).filterIt(it mod 6 != 0)
  baz = collect:
    for i in 1..10:
      let j = 2 * i
      if j mod 6 != 0:
        j

doAssert foo == bar
doAssert foo == baz
doAssert foo == @[2, 4, 8, 10, 14, 16, 20]

doAssert foo.any(x => x > 17)
doAssert not bar.allIt(it < 20)
doAssert foo.foldl(a + b) == 74 # sum of all members

Пример:

import std/sequtils
from std/strutils import join

let
  vowels = @"aeiou"
  foo = "sequtils is an awesome module"

doAssert (vowels is seq[char]) and (vowels == @['a', 'e', 'i', 'o', 'u'])
doAssert foo.filterIt(it notin vowels).join == "sqtls s n wsm mdl"

См. также

  • модуль strutils для общих функций для строк
  • модуль sugar для синтаксического сахара макросов
  • модуль algorithm для общих алгоритмов
  • модуль json для структуры, которая позволяет гетерогенные члены

Импорты

since, macros, typetraits

Процедуры

func addUnique[T](s: var seq[T]; x: sink T)
Добавляет x в контейнер s, если он в нём ещё не присутствует. Использует == для проверки наличия элемента.

Пример:

var a = @[1, 2, 3]
a.addUnique(4)
a.addUnique(4)
assert a == @[1, 2, 3, 4]
Исходный код Редактировать
proc all[T](s: openArray[T]; pred: proc (x: T): bool {.closure.}): bool {.
    effectsOf: pred.}

Проходит по контейнеру и проверяет, удовлетворяет ли каждый элемент предикату.

См. также:

  • шаблон allIt
  • процедура any

Пример:

let numbers = @[1, 4, 5, 8, 9, 7, 4]
assert all(numbers, proc (x: int): bool = x < 10) == true
assert all(numbers, proc (x: int): bool = x < 9) == false
Исходный код Редактировать
proc any[T](s: openArray[T]; pred: proc (x: T): bool {.closure.}): bool {.
    effectsOf: pred.}

Проходит по контейнеру и проверяет, удовлетворяет ли хотя бы один элемент предикату.

См. также:

  • шаблон anyIt
  • процедура all

Пример:

let numbers = @[1, 4, 5, 8, 9, 7, 4]
assert any(numbers, proc (x: int): bool = x > 8) == true
assert any(numbers, proc (x: int): bool = x > 9) == false
Исходный код Редактировать
proc apply[T](s: openArray[T]; op: proc (x: T) {.closure.}) {.inline,
    effectsOf: op.}
То же, что и apply, но для процедуры, которая ничего не возвращает и не изменяет s напрямую.

Пример:

var message: string
apply([0, 1, 2, 3, 4], proc(item: int) = message.addInt item)
assert message == "01234"
Исходный код Редактировать
proc apply[T](s: var openArray[T]; op: proc (x: T): T {.closure.}) {.inline,
    effectsOf: op.}

Применяет op к каждому элементу в s, изменяя его напрямую.

Обратите внимание, что контейнер s должен быть объявлен как var, и требуется, чтобы типы входных и выходных данных были одинаковыми, так как s изменяется на месте. Функция-параметр принимает и возвращает переменную типа T.

См. также:

  • шаблон applyIt
  • процедура map

Пример:

var a = @["1", "2", "3", "4"]
apply(a, proc(x: string): string = x & "42")
assert a == @["142", "242", "342", "442"]
Исходный код Редактировать
proc apply[T](s: var openArray[T]; op: proc (x: var T) {.closure.}) {.inline,
    effectsOf: op.}

Применяет op к каждому элементу в s, изменяя его напрямую.

Обратите внимание, что контейнер s должен быть объявлен как var, так как s изменяется на месте. Функция-параметр принимает параметр типа var T.

См. также:

  • шаблон applyIt
  • процедура map

Пример:

var a = @["1", "2", "3", "4"]
apply(a, proc(x: var string) = x &= "42")
assert a == @["142", "242", "342", "442"]
Исходный код Редактировать
func concat[T](seqs: varargs[seq[T]]): seq[T]

Принимает несколько последовательностей элементов и возвращает их в новой последовательности. Все последовательности должны быть одного типа.

См. также:

  • функция distribute для обратной операции

Пример:

let
  s1 = @[1, 2, 3]
  s2 = @[4, 5]
  s3 = @[6, 7]
  total = concat(s1, s2, s3)
assert total == @[1, 2, 3, 4, 5, 6, 7]
Исходный код Редактировать
func count[T](s: openArray[T]; x: T): int
Возвращает количество вхождений элемента x в контейнере s.

Пример:

let
  a = @[1, 2, 2, 3, 2, 4, 2]
  b = "abracadabra"
assert count(a, 2) == 4
assert count(a, 99) == 0
assert count(b, 'r') == 2
Исходный код Редактировать
func cycle[T](s: openArray[T]; n: Natural): seq[T]
Возвращает новую последовательность с элементами контейнера s , повторёнными n раз. n должно быть неотрицательным числом (ноль или больше).

Пример:

let
  s = @[1, 2, 3]
  total = s.cycle(3)
assert total == @[1, 2, 3, 1, 2, 3, 1, 2, 3]
Исходный код Редактировать
func deduplicate[T](s: openArray[T]; isSorted: bool = false): seq[T]

Возвращает новую последовательность без дубликатов.

Установка необязательного аргумента isSorted в значение true (по умолчанию: false) использует более быстрый алгоритм для удаления дубликатов.

Пример:

let
  dup1 = @[1, 1, 3, 4, 2, 2, 8, 1, 4]
  dup2 = @["a", "a", "c", "d", "d"]
  unique1 = deduplicate(dup1)
  unique2 = deduplicate(dup2, isSorted = true)
assert unique1 == @[1, 3, 4, 2, 8]
assert unique2 == @["a", "c", "d"]
Исходный код Редактировать
func delete[T](s: var seq[T]; first, last: Natural) {.
    ...deprecated: "use `delete(s, first..last)`".}
Устарело: используйте `delete(s, first..last)`
Удаляет элементы последовательности s по позициям first..last (включая обе границы диапазона). Это изменяет саму s, а не возвращает копию.

Пример: cmd: --warning:deprecated:off

let outcome = @[1, 1, 1, 1, 1, 1, 1, 1]
var dest = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
dest.delete(3, 8)
assert outcome == dest
Исходный код Редактировать
func delete[T](s: var seq[T]; slice: Slice[int])

Удаляет элементы s[slice], вызывая IndexDefect если срез содержит элементы, выходящие за пределы диапазона.

Эта операция перемещает все элементы после s[slice] за линейное время.

Пример:

var a = @[10, 11, 12, 13, 14]
doAssertRaises(IndexDefect): a.delete(4..5)
assert a == @[10, 11, 12, 13, 14]
a.delete(4..4)
assert a == @[10, 11, 12, 13]
a.delete(1..2)
assert a == @[10, 13]
a.delete(1..<1) # empty slice
assert a == @[10, 13]
Исходный код Редактировать
func distribute[T](s: seq[T]; num: Positive; spread = true): seq[seq[T]]

Разбивает и распределяет последовательность s на num подпоследовательности.

Возвращает последовательность из num последовательностей. Для некоторых входных значений это обратная операция функции concat. Входная последовательность s может быть пустой, что приведет к созданию num пустых последовательностей.

Если spread ложно, и длина s не является кратной num, функция максимально заполнит первую подпоследовательность 1 + len(s) div num элементами, оставив остальные элементы в последней последовательности.

С другой стороны, если spread истинно, функция равномерно распределит остаток от деления по всем последовательностям, что делает результат более подходящим для многопоточности, где вы передаете равные по размеру рабочие блоки пулу потоков и хотите максимизировать использование ядер.

Пример:

let numbers = @[1, 2, 3, 4, 5, 6, 7]
assert numbers.distribute(3) == @[@[1, 2, 3], @[4, 5], @[6, 7]]
assert numbers.distribute(3, false) == @[@[1, 2, 3], @[4, 5, 6], @[7]]
assert numbers.distribute(6)[0] == @[1, 2]
assert numbers.distribute(6)[1] == @[3]
Исходный код Редактировать
proc filter[T](s: openArray[T]; pred: proc (x: T): bool {.closure.}): seq[T] {.
    inline, effectsOf: pred.}

Возвращает новую последовательность со всеми элементами s , которые удовлетворяют предикату pred (функции, которая возвращает bool).

Вместо использования map и filter, рассмотрите использование макроса collect из модуля sugar.

См. также:

  • макрос sugar.collect
  • шаблон filterIt
  • итератор filter
  • процедура keepIf для варианта на месте

Пример:

let
  colors = @["red", "yellow", "black"]
  f1 = filter(colors, proc(x: string): bool = x.len < 6)
  f2 = filter(colors, proc(x: string): bool = x.contains('y'))
assert f1 == @["red", "black"]
assert f2 == @["yellow"]
Исходный код Редактировать
func insert[T](dest: var seq[T]; src: openArray[T]; pos = 0)

Вставляет элементы из src в dest по позиции pos. Это изменяет саму dest, а не возвращает копию.

Обратите внимание, что элементы src и dest должны быть одного типа.

Пример:

var dest = @[1, 1, 1, 1, 1, 1, 1, 1]
let
  src = @[2, 2, 2, 2, 2, 2]
  outcome = @[1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1]
dest.insert(src, 3)
assert dest == outcome
Исходный код Редактировать
proc keepIf[T](s: var seq[T]; pred: proc (x: T): bool {.closure.}) {.inline,
    effectsOf: pred.}

Сохраняет элементы в переданной последовательности s , если они удовлетворяют предикату pred (функция, возвращающая bool).

Обратите внимание, что s должен быть объявлен как var.

Аналогично процедуре фильтрации, но изменяет последовательность непосредственно.

См. также:

  • шаблон keepItIf
  • процедура фильтрации

Пример:

var floats = @[13.0, 12.5, 5.8, 2.0, 6.1, 9.9, 10.1]
keepIf(floats, proc(x: float): bool = x > 10)
assert floats == @[13.0, 12.5, 10.1]
Исходный код Редактировать
proc map[T, S](s: openArray[T]; op: proc (x: T): S {.closure.}): seq[S] {.
    inline, effectsOf: op.}

Возвращает новую последовательность с результатами применения процедуры op к каждому элементу в контейнере s.

Поскольку входные данные не изменяются, вы можете использовать эту функцию для преобразования типа элементов в входном контейнере.

Вместо использования map и filter, рассмотрите использование макроса collect из модуля sugar.

См. также:

  • макрос sugar.collect
  • шаблон mapIt
  • процедура apply для варианта изменения на месте

Пример:

let
  a = @[1, 2, 3, 4]
  b = map(a, proc(x: int): string = $x)
assert b == @["1", "2", "3", "4"]
Исходный код Редактировать
func maxIndex[T](s: openArray[T]): int
Возвращает индекс максимального значения s. T должен иметь оператор <.

Пример:

let
  a = @[1, 2, 3, 4]
  b = @[6, 5, 4, 3]
  c = [2, -7, 8, -5]
  d = "ziggy"
assert maxIndex(a) == 3
assert maxIndex(b) == 0
assert maxIndex(c) == 2
assert maxIndex(d) == 0
Исходный код Редактировать
func minIndex[T](s: openArray[T]): int
Возвращает индекс минимального значения s. T должен иметь оператор <.

Пример:

let
  a = @[1, 2, 3, 4]
  b = @[6, 5, 4, 3]
  c = [2, -7, 8, -5]
  d = "ziggy"
assert minIndex(a) == 0
assert minIndex(b) == 3
assert minIndex(c) == 1
assert minIndex(d) == 2
Исходный код Редактировать
func minmax[T](x: openArray[T]): (T, T)
Минимальное и максимальное значения x. T должен иметь оператор <.
Исходный код Редактировать
proc repeat[T](x: T; n: Natural): seq[T]
Возвращает новую последовательность с элементом x , повторив его n раз. n должно быть неотрицательным числом (ноль или больше).

Пример:

let
  total = repeat(5, 3)
assert total == @[5, 5, 5]
Исходный код Редактировать
proc unzip[S, T](s: openArray[(S, T)]): (seq[S], seq[T])
Возвращает кортеж из двух последовательностей, полученных из последовательности кортежей с двумя полями.

Пример:

let
  zipped = @[(1, 'a'), (2, 'b'), (3, 'c')]
  unzipped1 = @[1, 2, 3]
  unzipped2 = @['a', 'b', 'c']
assert zipped.unzip() == (unzipped1, unzipped2)
assert zip(unzipped1, unzipped2).unzip() == (unzipped1, unzipped2)
Исходный код Редактировать
proc zip[S, T](s1: openArray[S]; s2: openArray[T]): seq[(S, T)]

Возвращает новую последовательность с комбинацией двух входных контейнеров.

Входные контейнеры могут быть разных типов. Если один контейнер короче, оставшиеся элементы в более длинном контейнере отбрасываются.

Примечание: Для Nim 1.0.x и более старых версий zip возвращала seq именованных кортежей с полями a и b Для версий Nim 1.1.x и более новых zip возвращает seq неименованных кортежей.

Пример:

let
  short = @[1, 2, 3]
  long = @[6, 5, 4, 3, 2, 1]
  words = @["one", "two", "three"]
  letters = "abcd"
  zip1 = zip(short, long)
  zip2 = zip(short, words)
assert zip1 == @[(1, 6), (2, 5), (3, 4)]
assert zip2 == @[(1, "one"), (2, "two"), (3, "three")]
assert zip1[2][0] == 3
assert zip2[1][1] == "two"
when (NimMajor, NimMinor) <= (1, 0):
  let
    zip3 = zip(long, letters)
  assert zip3 == @[(a: 6, b: 'a'), (5, 'b'), (4, 'c'), (3, 'd')]
  assert zip3[0].b == 'a'
else:
  let
    zip3: seq[tuple[num: int, letter: char]] = zip(long, letters)
  assert zip3 == @[(6, 'a'), (5, 'b'), (4, 'c'), (3, 'd')]
  assert zip3[0].letter == 'a'
Исходный код Редактировать

Итераторы

iterator filter[T](s: openArray[T]; pred: proc (x: T): bool {.closure.}): T {.
    effectsOf: pred.}

Итерируется по контейнеру s и выдает каждый элемент, удовлетворяющий предикату pred (функция, возвращающая bool).

Вместо использования map и filter, рассмотрите использование макроса collect из модуля sugar.

См. также:

  • макрос sugar.collect
  • процедура фильтрации
  • шаблон filterIt

Пример:

let numbers = @[1, 4, 5, 8, 9, 7, 4]
var evens = newSeq[int]()
for n in filter(numbers, proc (x: int): bool = x mod 2 == 0):
  evens.add(n)
assert evens == @[4, 8, 4]
Исходный код Редактировать
iterator items[T](xs: iterator (): T): T
Итерируется по каждому элементу, возвращенному итератором-замыканием. Это может показаться не особенно полезным само по себе, но это позволяет использовать итераторы-замыкания с шаблонами mapIt, filterIt, allIt, anyIt и т. д. Исходный код Редактировать

Макросы

macro mapLiterals(constructor, op: untyped; nested = true): untyped
Применяет op к каждому из атомарных литералов, таких как 3 или "abc" в указанном constructor AST. Это можно использовать для отображения каждого элемента массива на некоторый целевой тип:

Пример:

let x = mapLiterals([0.1, 1.2, 2.3, 3.4], int)
doAssert x is array[4, int]
doAssert x == [int(0.1), int(1.2), int(2.3), int(3.4)]
Если nested имеет значение true (по умолчанию), литералы заменяются повсюду в constructor AST, в противном случае рассматривается только первый уровень:

Пример:

let a = mapLiterals((1.2, (2.3, 3.4), 4.8), int)
let b = mapLiterals((1.2, (2.3, 3.4), 4.8), int, nested=false)
assert a == (1, (2, 3), 4)
assert b == (1, (2.3, 3.4), 4)

let c = mapLiterals((1, (2, 3), 4, (5, 6)), `$`)
let d = mapLiterals((1, (2, 3), 4, (5, 6)), `$`, nested=false)
assert c == ("1", ("2", "3"), "4", ("5", "6"))
assert d == ("1", (2, 3), "4", (5, 6))
Для constructor AST нет ограничений, она работает для вложенных кортежей массивов, наборов и т. д. Исходный код Редактировать

Шаблоны

template allIt(s, pred: untyped): bool

Итерируется по контейнеру и проверяет, выполняет ли каждый элемент предикат.

В отличие от процедуры all, предикат должен быть выражением, использующим переменную it для проверки, например: allIt("abba", it == 'a').

См. также:

  • процедура all
  • шаблон anyIt

Пример:

let numbers = @[1, 4, 5, 8, 9, 7, 4]
assert numbers.allIt(it < 10) == true
assert numbers.allIt(it < 9) == false
Исходный код Редактировать
template anyIt(s, pred: untyped): bool

Итерируется по контейнеру и проверяет, выполняет ли хотя бы один элемент предикат.

В отличие от процедуры any, предикат должен быть выражением, использующим переменную it для проверки, например: anyIt("abba", it == 'a').

См. также:

  • процедура any
  • шаблон allIt

Пример:

let numbers = @[1, 4, 5, 8, 9, 7, 4]
assert numbers.anyIt(it > 8) == true
assert numbers.anyIt(it > 9) == false
Исходный код Редактировать
template applyIt(varSeq, op: untyped)

Удобный шаблон вокруг изменяемой apply процедуры для сокращения набора текста.

Шаблон вставляет переменную it, которую можно использовать непосредственно в выражении. Выражение должно возвращать тот же тип, что и элементы последовательности, которую вы изменяете.

См. также:

  • процедура apply
  • шаблон mapIt

Пример:

var nums = @[1, 2, 3, 4]
nums.applyIt(it * 3)
assert nums[0] + nums[3] == 15
Исходный код Редактировать
template countIt(s, pred: untyped): int

Возвращает количество элементов, удовлетворяющих предикату.

Предикат должен быть выражением, использующим переменную it для проверки, например: countIt(@[1, 2, 3], it > 2).

Пример:

let numbers = @[-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
iterator iota(n: int): int =
  for i in 0..<n: yield i
assert numbers.countIt(it < 0) == 3
assert countIt(iota(10), it < 2) == 2
Исходный код Редактировать
template filterIt(s, pred: untyped): untyped

Возвращает новую последовательность со всеми элементами s , которые удовлетворяют предикату pred.

В отличие от процедуры filter и итератора filter, предикат должен быть выражением, использующим переменную it для проверки, например: filterIt("abcxyz", it == 'x').

Вместо использования mapIt и filterIt, рассмотрите использование макроса collect из модуля sugar.

См. также:

  • макрос sugar.collect
  • процедура filter
  • итератор filter

Пример:

let
  temperatures = @[-272.15, -2.0, 24.5, 44.31, 99.9, -113.44]
  acceptable = temperatures.filterIt(it < 50 and it > -10)
  notAcceptable = temperatures.filterIt(it > 50 or it < -10)
assert acceptable == @[-2.0, 24.5, 44.31]
assert notAcceptable == @[-272.15, 99.9, -113.44]
Исходный код Редактировать
template foldl(sequence, operation, first): untyped

Шаблон для сложения последовательности слева направо, возвращающий накопление.

Эта версия foldl получает начальный параметр. Это позволяет накапливать последовательность в тип, отличный от типа элементов последовательности.

Параметр operation должен быть выражением, использующим переменные a и b для каждого шага сложения. Параметр first — это начальное значение (первое a), и поэтому он определяет тип результата.

См. также:

  • шаблон foldr

Пример:

let
  numbers = @[0, 8, 1, 5]
  digits = foldl(numbers, a & (chr(b + ord('0'))), "")
assert digits == "0815"
Исходный код Редактировать
template foldl(sequence, operation: untyped): untyped

Шаблон для сложения последовательности слева направо, возвращающий накопление.

Последовательность должна иметь по меньшей мере один элемент. В отладочных версиях вашей программы это вызовет ошибку, но в релизных версиях всё будет работать. Если последовательность содержит только один элемент, он будет возвращён без применения operation.

Параметр operation должен быть выражением, использующим переменные a и b для каждого шага сложения. Поскольку это левое сложение, для неассоциативных бинарных операций, таких как вычитание, последовательность чисел 1, 2 и 3 будет скобоваться как (((1) - 2) - 3).

См. также:

  • шаблон foldl с начальным параметром
  • шаблон foldr

Пример:

let
  numbers = @[5, 9, 11]
  addition = foldl(numbers, a + b)
  subtraction = foldl(numbers, a - b)
  multiplication = foldl(numbers, a * b)
  words = @["nim", "is", "cool"]
  concatenation = foldl(words, a & b)
  procs = @["proc", "Is", "Also", "Fine"]


func foo(acc, cur: string): string =
  result = acc & cur

assert addition == 25, "Addition is (((5)+9)+11)"
assert subtraction == -15, "Subtraction is (((5)-9)-11)"
assert multiplication == 495, "Multiplication is (((5)*9)*11)"
assert concatenation == "nimiscool"
assert foldl(procs, foo(a, b)) == "procIsAlsoFine"
Исходный код Редактировать
template foldr(sequence, operation: untyped): untyped

Шаблон для сложения последовательности справа налево, возвращающий накопление.

Последовательность должна иметь по меньшей мере один элемент. В отладочных версиях вашей программы это вызовет ошибку, но в релизных версиях всё будет работать. Если последовательность содержит только один элемент, он будет возвращён без применения operation.

Параметр operation должен быть выражением, использующим переменные a и b для каждого шага сложения. Поскольку это правое сложение, для неассоциативных бинарных операций, таких как вычитание, последовательность чисел 1, 2 и 3 будет скобоваться как (1 - (2 - (3))).

См. также:

  • шаблон foldl
  • шаблон foldl с начальным параметром

Пример:

let
  numbers = @[5, 9, 11]
  addition = foldr(numbers, a + b)
  subtraction = foldr(numbers, a - b)
  multiplication = foldr(numbers, a * b)
  words = @["nim", "is", "cool"]
  concatenation = foldr(words, a & b)
assert addition == 25, "Addition is (5+(9+(11)))"
assert subtraction == 7, "Subtraction is (5-(9-(11)))"
assert multiplication == 495, "Multiplication is (5*(9*(11)))"
assert concatenation == "nimiscool"
Исходный код Редактировать
template keepItIf(varSeq: seq; pred: untyped)

Сохраняет элементы в переданной последовательности (должна быть объявлена как var) если они удовлетворяют предикату.

В отличие от процедуры keepIf, предикат должен быть выражением, использующим переменную it для проверки, например: keepItIf("abcxyz", it == 'x').

См. также:

  • процедура keepIf
  • шаблон filterIt

Пример:

var candidates = @["foo", "bar", "baz", "foobar"]
candidates.keepItIf(it.len == 3 and it[0] == 'b')
assert candidates == @["bar", "baz"]
Исходный код Редактировать
template mapIt(s: typed; op: untyped): untyped

Возвращает новую последовательность с результатами применения op процедуры к каждому элементу в контейнере s.

Поскольку входные данные не изменяются, можно использовать его для преобразования типа элементов в входном контейнере.

Шаблон вставляет переменную it, которую можно использовать непосредственно в выражении.

Вместо использования mapIt и filterIt, рассмотрите использование макроса collect из модуля sugar.

См. также:

  • макрос sugar.collect
  • процедура map
  • шаблон applyIt для варианта на месте

Пример:

let
  nums = @[1, 2, 3, 4]
  strings = nums.mapIt($(4 * it))
assert strings == @["4", "8", "12", "16"]
Исходный код Редактировать
template newSeqWith(len: int; init: untyped): untyped

Создаёт новую seq длиной len, вызывая init для инициализации каждого значения в последовательности.

Полезно для создания «двумерных» последовательностей — последовательностей, содержащих другие последовательности, или для заполнения полей созданной последовательности.

Пример:

## Creates a seq containing 5 bool seqs, each of length of 3.
var seq2D = newSeqWith(5, newSeq[bool](3))
assert seq2D.len == 5
assert seq2D[0].len == 3
assert seq2D[4][2] == false

## Creates a seq with random numbers
import std/random
var seqRand = newSeqWith(20, rand(1.0))
assert seqRand[0] != seqRand[1]
Исходный код Редактировать
END_OF_DOCUMENT_MARKER
template toSeq(iter: untyped): untyped
Преобразует любой итерируемый объект (любой объект, по которому можно выполнить итерацию, например, с помощью цикла for) в последовательность.

Пример:

let
  myRange = 1..5
  mySet: set[int8] = {5'i8, 3, 1}
assert typeof(myRange) is HSlice[system.int, system.int]
assert typeof(mySet) is set[int8]

let
  mySeq1 = toSeq(myRange)
  mySeq2 = toSeq(mySet)
assert mySeq1 == @[1, 2, 3, 4, 5]
assert mySeq2 == @[1'i8, 3, 5]
Исходный код Редактировать

© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/sequtils.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API