Iterators

14.1 Inline Iterators

Inline iterators are inlined at the call site (zero overhead). They can only be used in for loops.

iterator countTo(n: int): int =
  var i = 0
  while i <= n:
    yield i
    inc i

for x in countTo(3): echo x

iterator pairsReversed[T](s: seq[T]): (int, T) =
  for i in countdown(s.high, 0): yield (i, s[i])

14.2 Closure Iterators

Closure iterators can be stored, passed around, and resumed. They're the building block of async.

iterator fib(): int {.closure.} =
  var (a, b) = (0, 1)
  while true:
    yield a
    (a, b) = (b, a + b)

let gen = fib
for _ in 0..9: echo gen()
echo finished(gen)

14.3 Implicit Iterators items and pairs

type Bag = object
  data: seq[int]
iterator items(b: Bag): int =
  for x in b.data: yield x
iterator pairs(b: Bag): (int, int) =
  for i, x in b.data: yield (i, x)
for x in Bag(data: @[1, 2]): echo x
iterator mitems(b: var Bag): var int =
  for x in b.data.mitems: yield x      # mutate elements in place

14.4 Iterator Utilities

toSeq(iter), std/iterutils patterns, sugar.collect, enumerate (from std/enumerate), zip.