# system/iterators

Dark Mode

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

# Iterators

    iterator fieldPairs[S: tuple | object; T: tuple | object](x: S; y: T): tuple[
        key: string, a, b: RootObj] {.magic: "FieldPairs", noSideEffect, ...raises: [],
                                      tags: [].}

  Iterates over every field of `x` and `y`.
  Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

  Example:

      type Foo = object
        x1: int
        x2: string
      var a1 = Foo(x1: 12, x2: "abc")
      var a2: Foo
      for name, v1, v2 in fieldPairs(a1, a2):
        when name == "x2": v2 = v1
      doAssert a2 == Foo(x1: 0, x2: "abc")

  Source Edit

    iterator fieldPairs[T: tuple | object](x: T): tuple[key: string, val: RootObj] {.
        magic: "FieldPairs", noSideEffect, ...raises: [], tags: [].}

  Iterates over every field of `x` returning their name and value.

  When you iterate over objects with different field types you have to use the compile time `when` instead of a runtime `if` to select the code you want to run for each type. To perform the comparison use the is operator. Another way to do the same without `when` is to leave the task of picking the appropriate code to a secondary proc which you overload for each field type and pass the `value` to.

  Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

  Example:

      type
        Custom = object
          foo: string
          bar: bool
      proc `$`(x: Custom): string =
        result = "Custom:"
        for name, value in x.fieldPairs:
          when value is bool:
            result.add("\n\t" & name & " is " & $value)
          else:
            result.add("\n\t" & name & " '" & value & "'")

  Source Edit

    iterator fields[S: tuple | object; T: tuple | object](x: S; y: T): tuple[
        key: string, val: RootObj] {.magic: "Fields", noSideEffect, ...raises: [],
                                     tags: [].}

  Iterates over every field of `x` and `y`.
  Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

  Example:

      var t1 = (1, "foo")
      var t2 = default(typeof(t1))
      for v1, v2 in fields(t1, t2): v2 = v1
      doAssert t1 == t2

  Source Edit

    iterator fields[T: tuple | object](x: T): RootObj {.magic: "Fields",
        noSideEffect, ...raises: [], tags: [].}

  Iterates over every field of `x`.
  Warning: This really transforms the 'for' and unrolls the loop. The current implementation also has a bug that affects symbol binding in the loop body.

  Example:

      var t = (1, "foo")
      for v in fields(t): v = default(typeof(v))
      doAssert t == (0, "")

  Source Edit

    iterator items(a: cstring): char {.inline, ...raises: [], tags: [].}

  Iterates over each item of `a`.

  Example:

      from std/sequtils import toSeq
      assert toSeq("abc\0def".cstring) == @['a', 'b', 'c']
      assert toSeq("abc".cstring) == @['a', 'b', 'c']

  Source Edit

    iterator items(a: string): char {.inline, ...raises: [], tags: [].}

  Iterates over each item of `a`. Source Edit

    iterator items[IX, T](a: array[IX, T]): T {.inline.}

  Iterates over each item of `a`. Source Edit

    iterator items[T: char](a: openArray[T]): T {.inline.}

  Iterates over each item of `a`. Source Edit

    iterator items[T: enum and Ordinal](E: typedesc[T]): T

  Iterates over the values of `E`. See also `enumutils.items` for enums with holes.

  Example:

      type Goo = enum g0 = 2, g1, g2
      from std/sequtils import toSeq
      assert Goo.toSeq == [g0, g1, g2]

  Source Edit

    iterator items[T: not char](a: openArray[T]): lent2 T {.inline.}

  Iterates over each item of `a`. Source Edit

    iterator items[T: Ordinal](s: Slice[T]): T

  Iterates over the slice `s`, yielding each value between `s.a` and `s.b` (inclusively). Source Edit

    iterator items[T](a: seq[T]): lent2 T {.inline.}

  Iterates over each item of `a`. Source Edit

    iterator items[T](a: set[T]): T {.inline.}

  Iterates over each element of `a`. `items` iterates only over the elements that are really in the set (and not over the ones the set is able to hold). Source Edit

    iterator mitems(a: var cstring): var char {.inline, ...raises: [], tags: [].}

  Iterates over each item of `a` so that you can modify the yielded value.

  Example:

      from std/sugar import collect
      var a = "abc\0def"
      var b = a.cstring
      let s = collect:
        for bi in mitems(b):
          if bi == 'b': bi = 'B'
          bi
      assert s == @['a', 'B', 'c']
      assert b == "aBc"
      assert a == "aBc\0def"

  Source Edit

    iterator mitems(a: var string): var char {.inline, ...raises: [], tags: [].}

  Iterates over each item of `a` so that you can modify the yielded value. Source Edit

    iterator mitems[IX, T](a: var array[IX, T]): var T {.inline.}

  Iterates over each item of `a` so that you can modify the yielded value. Source Edit

    iterator mitems[T](a: var openArray[T]): var T {.inline.}

  Iterates over each item of `a` so that you can modify the yielded value. Source Edit

    iterator mitems[T](a: var seq[T]): var T {.inline.}

  Iterates over each item of `a` so that you can modify the yielded value. Source Edit

    iterator mpairs(a: var cstring): tuple[key: int, val: var char] {.inline,
        ...raises: [], tags: [].}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. `a[index]` can be modified. Source Edit

    iterator mpairs(a: var string): tuple[key: int, val: var char] {.inline,
        ...raises: [], tags: [].}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. `a[index]` can be modified. Source Edit

    iterator mpairs[IX, T](a: var array[IX, T]): tuple[key: IX, val: var T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. `a[index]` can be modified. Source Edit

    iterator mpairs[T](a: var openArray[T]): tuple[key: int, val: var T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. `a[index]` can be modified. Source Edit

    iterator mpairs[T](a: var seq[T]): tuple[key: int, val: var T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. `a[index]` can be modified. Source Edit

    iterator pairs(a: cstring): tuple[key: int, val: char] {.inline, ...raises: [],
        tags: [].}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. Source Edit

    iterator pairs(a: string): tuple[key: int, val: char] {.inline, ...raises: [],
        tags: [].}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. Source Edit

    iterator pairs[IX, T](a: array[IX, T]): tuple[key: IX, val: T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. Source Edit

    iterator pairs[T](a: openArray[T]): tuple[key: int, val: T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. Source Edit

    iterator pairs[T](a: seq[T]): tuple[key: int, val: T] {.inline.}

  Iterates over each item of `a`. Yields `(index, a[index])` pairs. Source Edit