☰

# std/tables

Theme:

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

Search:
Source Edit

The `tables` module implements variants of an efficient hash table (also often named dictionary in other programming languages) that is a mapping from keys to values.

There are several different types of hash tables available:

- Table is the usual hash table,
- OrderedTable is like `Table` but remembers insertion order,
- CountTable is a mapping from a key to its number of occurrences

For consistency with every other data type in Nim these have value semantics, this means that `=` performs a copy of the hash table.

For ref semantics use their `Ref` variants: TableRef, OrderedTableRef, and CountTableRef.

To give an example, when `a` is a `Table`, then `var b = a` gives `b` as a new independent table. `b` is initialised with the contents of `a`. Changing `b` does not affect `a` and vice versa:

Example:

    import std/tables
    var
      a = {1: "one", 2: "two"}.toTable  # creates a Table
      b = a

    assert a == b

    b[3] = "three"
    assert 3 notin a
    assert 3 in b
    assert a != b

On the other hand, when `a` is a `TableRef` instead, then changes to `b` also affect `a`. Both `a` and `b` ref the same data structure:

Example:

    import std/tables
    var
      a = {1: "one", 2: "two"}.newTable  # creates a TableRef
      b = a

    assert a == b

    b[3] = "three"

    assert 3 in a
    assert 3 in b
    assert a == b

# Basic usage

## Table

Example:

    import std/tables
    from std/sequtils import zip

    let
      names = ["John", "Paul", "George", "Ringo"]
      years = [1940, 1942, 1943, 1940]

    var beatles = initTable[string, int]()

    for pairs in zip(names, years):
      let (name, birthYear) = pairs
      beatles[name] = birthYear

    assert beatles == {"George": 1943, "Ringo": 1940, "Paul": 1942, "John": 1940}.toTable

    var beatlesByYear = initTable[int, seq[string]]()

    for pairs in zip(years, names):
      let (birthYear, name) = pairs
      if not beatlesByYear.hasKey(birthYear):
        # if a key doesn't exist, we create one with an empty sequence
        # before we can add elements to it
        beatlesByYear[birthYear] = @[]
      beatlesByYear[birthYear].add(name)

    assert beatlesByYear == {1940: @["John", "Ringo"], 1942: @["Paul"], 1943: @["George"]}.toTable

## OrderedTable

OrderedTable is used when it is important to preserve the insertion order of keys.

Example:

    import std/tables
    let
      a = [('z', 1), ('y', 2), ('x', 3)]
      ot = a.toOrderedTable  # ordered tables

    assert $ot == """{'z': 1, 'y': 2, 'x': 3}"""

## CountTable

CountTable is useful for counting number of items of some container (e.g. string, sequence or array), as it is a mapping where the items are the keys, and their number of occurrences are the values. For that purpose toCountTable proc comes in handy:

Example:

    import std/tables
    let myString = "abracadabra"
    let letterFrequencies = toCountTable(myString)
    assert $letterFrequencies == "{'a': 5, 'd': 1, 'b': 2, 'r': 2, 'c': 1}"

The same could have been achieved by manually iterating over a container and increasing each key's value with inc proc:

Example:

    import std/tables
    let myString = "abracadabra"
    var letterFrequencies = initCountTable[char]()
    for c in myString:
      letterFrequencies.inc(c)
    assert $letterFrequencies == "{'d': 1, 'r': 2, 'c': 1, 'a': 5, 'b': 2}"

## Hashing

If you are using simple standard types like `int` or `string` for the keys of the table you won't have any problems, but as soon as you try to use a more complex object as a key you will be greeted by a strange compiler error:

    Error: type mismatch: got (Person)
    but expected one of:
    hashes.hash(x: openArray[A]): Hash
    hashes.hash(x: int): Hash
    hashes.hash(x: float): Hash

What is happening here is that the types used for table keys require to have a `hash()` proc which will convert them to a Hash value, and the compiler is listing all the hash functions it knows. Additionally there has to be a `==` operator that provides the same semantics as its corresponding `hash` proc.

After you add `hash` and `==` for your custom type everything will work. Currently, however, `hash` for objects is not defined, whereas `system.==` for objects does exist and performs a "deep" comparison (every field is compared) which is usually what you want. So in the following example implementing only `hash` suffices:

Example:

    import std/tables
    import std/hashes

    type
      Person = object
        firstName, lastName: string

    proc hash(x: Person): Hash =
      ## Piggyback on the already available string hash proc.
      ##
      ## Without this proc nothing works!
      result = x.firstName.hash !& x.lastName.hash
      result = !$result

    var
      salaries = initTable[Person, int]()
      p1, p2: Person

    p1.firstName = "Jon"
    p1.lastName = "Ross"
    salaries[p1] = 30_000

    p2.firstName = "소진"
    p2.lastName = "박"
    salaries[p2] = 45_000

# See also

- json module for table-like structure which allows heterogeneous members
- strtabs module for efficient hash tables mapping from strings to strings
- hashes module for helper functions for hashing

# Imports

since, hashes, math, algorithm, assertions, outparams

# Types

    CountTable[A] = object

  Hash table that counts the number of each key. Unlike Table, this uses a zero count to signal "empty" & so does not cache hash values for comparison reduction or resize acceleration.

  For creating an empty CountTable, use initCountTable proc.

  Source Edit

    CountTableRef[A] = ref CountTable[A]

  Ref version of CountTable.

  For creating a new empty CountTableRef, use newCountTable proc.

  Source Edit

    OrderedTable[A; B] = object

  Hash table that remembers insertion order.

  For creating an empty OrderedTable, use initOrderedTable proc.

  Source Edit

    OrderedTableRef[A; B] = ref OrderedTable[A, B]

  Ref version of OrderedTable.

  For creating a new empty OrderedTableRef, use newOrderedTable proc.

  Source Edit

    Table[A; B] = object

  Generic hash table, consisting of a key-value pair.

  `data` and `counter` are internal implementation details which can't be accessed.

  For creating an empty Table, use initTable proc.

  Source Edit

    TableRef[A; B] = ref Table[A, B]

  Ref version of Table.

  For creating a new empty TableRef, use newTable proc.

  Source Edit

# Consts

    defaultInitialSize = 32

  Source Edit

# Procs

    proc `$`[A, B](t: OrderedTable[A, B]): string

  The `$` operator for ordered hash tables. Used internally when calling `echo` on a table. Source Edit

    proc `$`[A, B](t: OrderedTableRef[A, B]): string

  The `$` operator for hash tables. Used internally when calling `echo` on a table. Source Edit

    proc `$`[A, B](t: Table[A, B]): string

  The `$` operator for hash tables. Used internally when calling `echo` on a table. Source Edit

    proc `$`[A, B](t: TableRef[A, B]): string

  The `$` operator for hash tables. Used internally when calling `echo` on a table. Source Edit

    proc `$`[A](t: CountTable[A]): string

  The `$` operator for count tables. Used internally when calling `echo` on a table. Source Edit

    proc `$`[A](t: CountTableRef[A]): string

  The `$` operator for count tables. Used internally when calling `echo` on a table. Source Edit

    proc `==`[A, B](s, t: OrderedTable[A, B]): bool

  The `==` operator for ordered hash tables. Returns `true` if both the content and the order are equal.

  Example:

      let
        a = {'a': 5, 'b': 9, 'c': 13}.toOrderedTable
        b = {'b': 9, 'c': 13, 'a': 5}.toOrderedTable
      doAssert a != b

  Source Edit

    proc `==`[A, B](s, t: OrderedTableRef[A, B]): bool

  The `==` operator for ordered hash tables. Returns true if either both tables are `nil`, or neither is `nil` and the content and the order of both are equal.

  Example:

      let
        a = {'a': 5, 'b': 9, 'c': 13}.newOrderedTable
        b = {'b': 9, 'c': 13, 'a': 5}.newOrderedTable
      doAssert a != b

  Source Edit

    proc `==`[A, B](s, t: Table[A, B]): bool

  The `==` operator for hash tables. Returns `true` if the content of both tables contains the same key-value pairs. Insert order does not matter.

  Example:

      let
        a = {'a': 5, 'b': 9, 'c': 13}.toTable
        b = {'b': 9, 'c': 13, 'a': 5}.toTable
      doAssert a == b

  Source Edit

    proc `==`[A, B](s, t: TableRef[A, B]): bool

  The `==` operator for hash tables. Returns `true` if either both tables are `nil`, or neither is `nil` and the content of both tables contains the same key-value pairs. Insert order does not matter.

  Example:

      let
        a = {'a': 5, 'b': 9, 'c': 13}.newTable
        b = {'b': 9, 'c': 13, 'a': 5}.newTable
      doAssert a == b

  Source Edit

    proc `==`[A](s, t: CountTable[A]): bool

  The `==` operator for count tables. Returns `true` if both tables contain the same keys with the same count. Insert order does not matter. Source Edit

    proc `==`[A](s, t: CountTableRef[A]): bool

  The `==` operator for count tables. Returns `true` if either both tables are `nil`, or neither is `nil` and both contain the same keys with the same count. Insert order does not matter. Source Edit

    proc `[]`[A, B](t: OrderedTable[A, B]; key: A): lent B

  Retrieves the value at `t[key]`.

  If `key` is not in `t`, the `KeyError` exception is raised. One can check with hasKey proc whether the key exists.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert a['a'] == 5
      doAssertRaises(KeyError):
        echo a['z']

  Source Edit

    proc `[]`[A, B](t: OrderedTableRef[A, B]; key: A): var B

  Retrieves the value at `t[key]`.

  If `key` is not in `t`, the `KeyError` exception is raised. One can check with hasKey proc whether the key exists.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert a['a'] == 5
      doAssertRaises(KeyError):
        echo a['z']

  Source Edit

    proc `[]`[A, B](t: Table[A, B]; key: A): lent B

  Retrieves the value at `t[key]`.

  If `key` is not in `t`, the `KeyError` exception is raised. One can check with hasKey proc whether the key exists.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert a['a'] == 5
      doAssertRaises(KeyError):
        echo a['z']

  Source Edit

    proc `[]`[A, B](t: TableRef[A, B]; key: A): var B

  Retrieves the value at `t[key]`.

  If `key` is not in `t`, the `KeyError` exception is raised. One can check with hasKey proc whether the key exists.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert a['a'] == 5
      doAssertRaises(KeyError):
        echo a['z']

  Source Edit

    proc `[]`[A, B](t: var OrderedTable[A, B]; key: A): var B

  Retrieves the value at `t[key]`. The value can be modified.

  If `key` is not in `t`, the `KeyError` exception is raised.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc `[]`[A, B](t: var Table[A, B]; key: A): var B

  Retrieves the value at `t[key]`. The value can be modified.

  If `key` is not in `t`, the `KeyError` exception is raised.

  See also:

  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc `[]`[A](t: CountTable[A]; key: A): int

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise `0` is returned.

  See also:

  - getOrDefault to return a custom value if the key doesn't exist
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc `[]`[A](t: CountTableRef[A]; key: A): int

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise `0` is returned.

  See also:

  - getOrDefault to return a custom value if the key doesn't exist
  - inc proc to inc even if missing
  - []= proc for inserting a new (key, value) pair in the table
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc `[]=`[A, B](t: OrderedTableRef[A, B]; key: A; val: sink B)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - hasKeyOrPut proc
  - mgetOrPut proc
  - del proc for removing a key from the table

  Example:

      var a = newOrderedTable[char, int]()
      a['x'] = 7
      a['y'] = 33
      doAssert a == {'x': 7, 'y': 33}.newOrderedTable

  Source Edit

    proc `[]=`[A, B](t: TableRef[A, B]; key: A; val: sink B)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - hasKeyOrPut proc
  - mgetOrPut proc
  - del proc for removing a key from the table

  Example:

      var a = newTable[char, int]()
      a['x'] = 7
      a['y'] = 33
      doAssert a == {'x': 7, 'y': 33}.newTable

  Source Edit

    proc `[]=`[A, B](t: var OrderedTable[A, B]; key: A; val: sink B)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - hasKeyOrPut proc
  - mgetOrPut proc
  - del proc for removing a key from the table

  Example:

      var a = initOrderedTable[char, int]()
      a['x'] = 7
      a['y'] = 33
      doAssert a == {'x': 7, 'y': 33}.toOrderedTable

  Source Edit

    proc `[]=`[A, B](t: var Table[A, B]; key: A; val: sink B)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - hasKeyOrPut proc
  - mgetOrPut proc
  - del proc for removing a key from the table

  Example:

      var a = initTable[char, int]()
      a['x'] = 7
      a['y'] = 33
      doAssert a == {'x': 7, 'y': 33}.toTable

  Source Edit

    proc `[]=`[A](t: CountTableRef[A]; key: A; val: int)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - inc proc for incrementing a value of a key
  Source Edit

    proc `[]=`[A](t: var CountTable[A]; key: A; val: int)

  Inserts a `(key, value)` pair into `t`.

  See also:

  - [] proc for retrieving a value of a key
  - inc proc for incrementing a value of a key
  Source Edit

    proc add[A, B](t: OrderedTableRef[A, B]; key: A; val: sink B) {....deprecated: "Deprecated since v1.4; it was more confusing than useful, use `[]=`".}

  Deprecated: Deprecated since v1.4; it was more confusing than useful, use `[]=`

  Puts a new `(key, value)` pair into `t` even if `t[key]` already exists.

  This can introduce duplicate keys into the table!

  Use []= proc for inserting a new (key, value) pair in the table without introducing duplicates.

  Source Edit

    proc add[A, B](t: TableRef[A, B]; key: A; val: sink B) {....deprecated: "Deprecated since v1.4; it was more confusing than useful, use `[]=`".}

  Deprecated: Deprecated since v1.4; it was more confusing than useful, use `[]=`

  Puts a new `(key, value)` pair into `t` even if `t[key]` already exists.

  This can introduce duplicate keys into the table!

  Use []= proc for inserting a new (key, value) pair in the table without introducing duplicates.

  Source Edit

    proc add[A, B](t: var OrderedTable[A, B]; key: A; val: sink B) {....deprecated: "Deprecated since v1.4; it was more confusing than useful, use `[]=`".}

  Deprecated: Deprecated since v1.4; it was more confusing than useful, use `[]=`

  Puts a new `(key, value)` pair into `t` even if `t[key]` already exists.

  This can introduce duplicate keys into the table!

  Use []= proc for inserting a new (key, value) pair in the table without introducing duplicates.

  Source Edit

    proc add[A, B](t: var Table[A, B]; key: A; val: sink B) {....deprecated: "Deprecated since v1.4; it was more confusing than useful, use `[]=`".}

  Deprecated: Deprecated since v1.4; it was more confusing than useful, use `[]=`

  Puts a new `(key, value)` pair into `t` even if `t[key]` already exists.

  This can introduce duplicate keys into the table!

  Use []= proc for inserting a new (key, value) pair in the table without introducing duplicates.

  Source Edit

    proc clear[A, B](t: OrderedTableRef[A, B])

  Resets the table so that it is empty.

  See also:

  - del proc

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.newOrderedTable
      doAssert len(a) == 3
      clear(a)
      doAssert len(a) == 0

  Source Edit

    proc clear[A, B](t: TableRef[A, B])

  Resets the table so that it is empty.

  See also:

  - del proc
  - pop proc

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.newTable
      doAssert len(a) == 3
      clear(a)
      doAssert len(a) == 0

  Source Edit

    proc clear[A, B](t: var OrderedTable[A, B])

  Resets the table so that it is empty.

  See also:

  - del proc
  - pop proc

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.toOrderedTable
      doAssert len(a) == 3
      clear(a)
      doAssert len(a) == 0

  Source Edit

    proc clear[A, B](t: var Table[A, B])

  Resets the table so that it is empty.

  See also:

  - del proc
  - pop proc

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.toTable
      doAssert len(a) == 3
      clear(a)
      doAssert len(a) == 0

  Source Edit

    proc clear[A](t: CountTableRef[A])

  Resets the table so that it is empty.

  See also:

  - del proc
  - pop proc
  Source Edit

    proc clear[A](t: var CountTable[A])

  Resets the table so that it is empty.

  See also:

  - del proc
  - pop proc
  Source Edit

    proc contains[A, B](t: OrderedTable[A, B]; key: A): bool

  Alias of hasKey proc for use with the `in` operator.

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert 'b' in a == true
      doAssert a.contains('z') == false

  Source Edit

    proc contains[A, B](t: OrderedTableRef[A, B]; key: A): bool

  Alias of hasKey proc for use with the `in` operator.

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert 'b' in a == true
      doAssert a.contains('z') == false

  Source Edit

    proc contains[A, B](t: Table[A, B]; key: A): bool

  Alias of hasKey proc for use with the `in` operator.

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert 'b' in a == true
      doAssert a.contains('z') == false

  Source Edit

    proc contains[A, B](t: TableRef[A, B]; key: A): bool

  Alias of hasKey proc for use with the `in` operator.

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert 'b' in a == true
      doAssert a.contains('z') == false

  Source Edit

    proc contains[A](t: CountTable[A]; key: A): bool

  Alias of hasKey proc for use with the `in` operator. Source Edit

    proc contains[A](t: CountTableRef[A]; key: A): bool

  Alias of hasKey proc for use with the `in` operator. Source Edit

    proc del[A, B](t: OrderedTableRef[A, B]; key: A)

  Deletes `key` from hash table `t`. Does nothing if the key does not exist.

  See also:

  - clear proc to empty the whole table

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.newOrderedTable
      a.del('a')
      doAssert a == {'b': 9, 'c': 13}.newOrderedTable
      a.del('z')
      doAssert a == {'b': 9, 'c': 13}.newOrderedTable

  Source Edit

    proc del[A, B](t: TableRef[A, B]; key: A)

  Deletes `key` from hash table `t`. Does nothing if the key does not exist.
  Warning: If duplicate keys were added (via the now deprecated `add` proc), this may need to be called multiple times.

  See also:

  - pop proc
  - clear proc to empty the whole table

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.newTable
      a.del('a')
      doAssert a == {'b': 9, 'c': 13}.newTable
      a.del('z')
      doAssert a == {'b': 9, 'c': 13}.newTable

  Source Edit

    proc del[A, B](t: var OrderedTable[A, B]; key: A)

  Deletes `key` from hash table `t`. Does nothing if the key does not exist.

  O(n) complexity.

  See also:

  - pop proc
  - clear proc to empty the whole table

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.toOrderedTable
      a.del('a')
      doAssert a == {'b': 9, 'c': 13}.toOrderedTable
      a.del('z')
      doAssert a == {'b': 9, 'c': 13}.toOrderedTable

  Source Edit

    proc del[A, B](t: var Table[A, B]; key: A)

  Deletes `key` from hash table `t`. Does nothing if the key does not exist.
  Warning: If duplicate keys were added (via the now deprecated `add` proc), this may need to be called multiple times.

  See also:

  - pop proc
  - clear proc to empty the whole table

  Example:

      var a = {'a': 5, 'b': 9, 'c': 13}.toTable
      a.del('a')
      doAssert a == {'b': 9, 'c': 13}.toTable
      a.del('z')
      doAssert a == {'b': 9, 'c': 13}.toTable

  Source Edit

    proc del[A](t: CountTableRef[A]; key: A)

  Deletes `key` from table `t`. Does nothing if the key does not exist.

  See also:

  - pop proc
  - clear proc to empty the whole table
  Source Edit

    proc del[A](t: var CountTable[A]; key: A)

  Deletes `key` from table `t`. Does nothing if the key does not exist.

  See also:

  - pop proc
  - clear proc to empty the whole table

  Example:

      var a = toCountTable("aabbbccccc")
      a.del('b')
      assert a == toCountTable("aaccccc")
      a.del('b')
      assert a == toCountTable("aaccccc")
      a.del('c')
      assert a == toCountTable("aa")

  Source Edit

    proc getOrDefault[A, B](t: OrderedTable[A, B]; key: A): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the default initialization value for type `B` is returned (e.g. 0 for any integer type).

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert a.getOrDefault('a') == 5
      doAssert a.getOrDefault('z') == 0

  Source Edit

    proc getOrDefault[A, B](t: OrderedTable[A, B]; key: A; def: B): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert a.getOrDefault('a', 99) == 5
      doAssert a.getOrDefault('z', 99) == 99

  Source Edit

    proc getOrDefault[A, B](t: OrderedTableRef[A, B]; key: A): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the default initialization value for type `B` is returned (e.g. 0 for any integer type).

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert a.getOrDefault('a') == 5
      doAssert a.getOrDefault('z') == 0

  Source Edit

    proc getOrDefault[A, B](t: OrderedTableRef[A, B]; key: A; def: B): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert a.getOrDefault('a', 99) == 5
      doAssert a.getOrDefault('z', 99) == 99

  Source Edit

    proc getOrDefault[A, B](t: Table[A, B]; key: A): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the default initialization value for type `B` is returned (e.g. 0 for any integer type).

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert a.getOrDefault('a') == 5
      doAssert a.getOrDefault('z') == 0

  Source Edit

    proc getOrDefault[A, B](t: Table[A, B]; key: A; def: B): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert a.getOrDefault('a', 99) == 5
      doAssert a.getOrDefault('z', 99) == 99

  Source Edit

    proc getOrDefault[A, B](t: TableRef[A, B]; key: A): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the default initialization value for type `B` is returned (e.g. 0 for any integer type).

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert a.getOrDefault('a') == 5
      doAssert a.getOrDefault('z') == 0

  Source Edit

    proc getOrDefault[A, B](t: TableRef[A, B]; key: A; def: B): B

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - mgetOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert a.getOrDefault('a', 99) == 5
      doAssert a.getOrDefault('z', 99) == 99

  Source Edit

    proc getOrDefault[A](t: CountTable[A]; key: A; def: int = 0): int

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the integer value of `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc getOrDefault[A](t: CountTableRef[A]; key: A; def: int): int

  Retrieves the value at `t[key]` if `key` is in `t`. Otherwise, the integer value of `def` is returned.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc for checking if a key is in the table
  Source Edit

    proc hash[K, V](s: OrderedTable[K, V]): Hash

  Source Edit

    proc hash[K, V](s: Table[K, V]): Hash

  Source Edit

    proc hash[V](s: CountTable[V]): Hash

  Source Edit

    proc hasKey[A, B](t: OrderedTable[A, B]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert a.hasKey('a') == true
      doAssert a.hasKey('z') == false

  Source Edit

    proc hasKey[A, B](t: OrderedTableRef[A, B]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert a.hasKey('a') == true
      doAssert a.hasKey('z') == false

  Source Edit

    proc hasKey[A, B](t: Table[A, B]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert a.hasKey('a') == true
      doAssert a.hasKey('z') == false

  Source Edit

    proc hasKey[A, B](t: TableRef[A, B]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert a.hasKey('a') == true
      doAssert a.hasKey('z') == false

  Source Edit

    proc hasKey[A](t: CountTable[A]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a custom value if the key doesn't exist
  Source Edit

    proc hasKey[A](t: CountTableRef[A]; key: A): bool

  Returns true if `key` is in the table `t`.

  See also:

  - contains proc for use with the `in` operator
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a custom value if the key doesn't exist
  Source Edit

    proc hasKeyOrPut[A, B](t: OrderedTableRef[A, B]; key: A; val: B): bool

  Returns true if `key` is in the table, otherwise inserts `value`.

  See also:

  - hasKey proc
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.newOrderedTable
      if a.hasKeyOrPut('a', 50):
        a['a'] = 99
      if a.hasKeyOrPut('z', 50):
        a['z'] = 99
      doAssert a == {'a': 99, 'b': 9, 'z': 50}.newOrderedTable

  Source Edit

    proc hasKeyOrPut[A, B](t: TableRef[A, B]; key: A; val: B): bool

  Returns true if `key` is in the table, otherwise inserts `value`.

  See also:

  - hasKey proc
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.newTable
      if a.hasKeyOrPut('a', 50):
        a['a'] = 99
      if a.hasKeyOrPut('z', 50):
        a['z'] = 99
      doAssert a == {'a': 99, 'b': 9, 'z': 50}.newTable

  Source Edit

    proc hasKeyOrPut[A, B](t: var OrderedTable[A, B]; key: A; val: B): bool

  Returns true if `key` is in the table, otherwise inserts `value`.

  See also:

  - hasKey proc
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.toOrderedTable
      if a.hasKeyOrPut('a', 50):
        a['a'] = 99
      if a.hasKeyOrPut('z', 50):
        a['z'] = 99
      doAssert a == {'a': 99, 'b': 9, 'z': 50}.toOrderedTable

  Source Edit

    proc hasKeyOrPut[A, B](t: var Table[A, B]; key: A; val: B): bool

  Returns true if `key` is in the table, otherwise inserts `value`.

  See also:

  - hasKey proc
  - [] proc for retrieving a value of a key
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.toTable
      if a.hasKeyOrPut('a', 50):
        a['a'] = 99
      if a.hasKeyOrPut('z', 50):
        a['z'] = 99
      doAssert a == {'a': 99, 'b': 9, 'z': 50}.toTable

  Source Edit

    proc inc[A](t: CountTableRef[A]; key: A; val = 1)

  Source Edit

    proc inc[A](t: var CountTable[A]; key: A; val = 1)

  Source Edit

    proc indexBy[A, B, C](collection: A; index: proc (x: B): C): Table[C, B]

  Index the collection with the proc provided. Source Edit

    proc initCountTable[A](initialSize = defaultInitialSize): CountTable[A]

  Creates a new count table that is empty.

  Starting from Nim v0.20, tables are initialized by default and it is not necessary to call this function explicitly.

  See also:

  - toCountTable proc
  - newCountTable proc for creating a `CountTableRef`
  Source Edit

    proc initOrderedTable[A, B](initialSize = defaultInitialSize): OrderedTable[A, B]

  Creates a new ordered hash table that is empty.

  Starting from Nim v0.20, tables are initialized by default and it is not necessary to call this function explicitly.

  See also:

  - toOrderedTable proc
  - newOrderedTable proc for creating an `OrderedTableRef`

  Example:

      let
        a = initOrderedTable[int, string]()
        b = initOrderedTable[char, seq[int]]()

  Source Edit

    proc initTable[A, B](initialSize = defaultInitialSize): Table[A, B]

  Creates a new hash table that is empty.

  Starting from Nim v0.20, tables are initialized by default and it is not necessary to call this function explicitly.

  See also:

  - toTable proc
  - newTable proc for creating a `TableRef`

  Example:

      let
        a = initTable[int, string]()
        b = initTable[char, seq[int]]()

  Source Edit

    proc largest[A](t: CountTable[A]): tuple[key: A, val: int]

  Returns the `(key, value)` pair with the largest `val`. Efficiency: O(n)

  See also:

  - smallest proc
  Source Edit

    proc largest[A](t: CountTableRef[A]): tuple[key: A, val: int]

  Returns the `(key, value)` pair with the largest `val`. Efficiency: O(n)

  See also:

  - smallest proc
  Source Edit

    proc len[A, B](t: OrderedTable[A, B]): int {.inline.}

  Returns the number of keys in `t`.

  Example:

      let a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert len(a) == 2

  Source Edit

    proc len[A, B](t: OrderedTableRef[A, B]): int {.inline.}

  Returns the number of keys in `t`.

  Example:

      let a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert len(a) == 2

  Source Edit

    proc len[A, B](t: Table[A, B]): int

  Returns the number of keys in `t`.

  Example:

      let a = {'a': 5, 'b': 9}.toTable
      doAssert len(a) == 2

  Source Edit

    proc len[A, B](t: TableRef[A, B]): int

  Returns the number of keys in `t`.

  Example:

      let a = {'a': 5, 'b': 9}.newTable
      doAssert len(a) == 2

  Source Edit

    proc len[A](t: CountTable[A]): int

  Returns the number of keys in `t`. Source Edit

    proc len[A](t: CountTableRef[A]): int

  Returns the number of keys in `t`. Source Edit

    proc merge[A](s, t: CountTableRef[A])

  Merges the second table into the first one.

  Example:

      let
        a = newCountTable("aaabbc")
        b = newCountTable("bcc")
      a.merge(b)
      doAssert a == newCountTable("aaabbbccc")

  Source Edit

    proc merge[A](s: var CountTable[A]; t: CountTable[A])

  Merges the second table into the first one (must be declared as `var`).

  Example:

      var a = toCountTable("aaabbc")
      let b = toCountTable("bcc")
      a.merge(b)
      doAssert a == toCountTable("aaabbbccc")

  Source Edit

    proc mgetOrPut[A, B](t: OrderedTableRef[A, B]; key: A): var B

  Retrieves the value at `t[key]` or puts the default initialization value for type `B` (e.g. 0 for any integer type).

  Example:

      var a = {'a': 5}.toOrderedTable
      doAssert a.mgetOrPut('a') == 5
      a.mgetOrPut('z').inc
      doAssert a == {'a': 5, 'z': 1}.toOrderedTable

  Source Edit

    proc mgetOrPut[A, B](t: OrderedTableRef[A, B]; key: A; val: B): var B

  Retrieves value at `t[key]` or puts `val` if not present, either way returning a value which can be modified.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.newOrderedTable
      doAssert a.mgetOrPut('a', 99) == 5
      doAssert a.mgetOrPut('z', 99) == 99
      doAssert a == {'a': 5, 'b': 9, 'z': 99}.newOrderedTable

  Source Edit

    proc mgetOrPut[A, B](t: TableRef[A, B]; key: A): var B

  Retrieves the value at `t[key]` or puts the default initialization value for type `B` (e.g. 0 for any integer type).

  Example:

      var a = {'a': 5}.newTable
      doAssert a.mgetOrPut('a') == 5
      a.mgetOrPut('z').inc
      doAssert a == {'a': 5, 'z': 1}.newTable

  Source Edit

    proc mgetOrPut[A, B](t: TableRef[A, B]; key: A; val: B): var B

  Retrieves value at `t[key]` or puts `val` if not present, either way returning a value which can be modified.

  Note that while the value returned is of type `var B`, it is easy to accidentally create an copy of the value at `t[key]`. Remember that seqs and strings are value types, and therefore cannot be copied into a separate variable for modification. See the example below.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.newTable
      doAssert a.mgetOrPut('a', 99) == 5
      doAssert a.mgetOrPut('z', 99) == 99
      doAssert a == {'a': 5, 'b': 9, 'z': 99}.newTable

      # An example of accidentally creating a copy
      var t = newTable[int, seq[int]]()
      # In this example, we expect t[10] to be modified,
      # but it is not.
      var copiedSeq = t.mgetOrPut(10, @[10])
      copiedSeq.add(20)
      doAssert t[10] == @[10]
      # Correct
      t.mgetOrPut(25, @[25]).add(35)
      doAssert t[25] == @[25, 35]

  Source Edit

    proc mgetOrPut[A, B](t: var OrderedTable[A, B]; key: A): var B

  Retrieves the value at `t[key]` or puts the default initialization value for type `B` (e.g. 0 for any integer type).

  Example:

      var a = {'a': 5}.toOrderedTable
      doAssert a.mgetOrPut('a') == 5
      a.mgetOrPut('z').inc
      doAssert a == {'a': 5, 'z': 1}.toOrderedTable

  Source Edit

    proc mgetOrPut[A, B](t: var OrderedTable[A, B]; key: A; val: B): var B

  Retrieves value at `t[key]` or puts `val` if not present, either way returning a value which can be modified.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.toOrderedTable
      doAssert a.mgetOrPut('a', 99) == 5
      doAssert a.mgetOrPut('z', 99) == 99
      doAssert a == {'a': 5, 'b': 9, 'z': 99}.toOrderedTable

  Source Edit

    proc mgetOrPut[A, B](t: var Table[A, B]; key: A): var B

  Retrieves the value at `t[key]` or puts the default initialization value for type `B` (e.g. 0 for any integer type).

  Example:

      var a = {'a': 5}.newTable
      doAssert a.mgetOrPut('a') == 5
      a.mgetOrPut('z').inc
      doAssert a == {'a': 5, 'z': 1}.newTable

  Source Edit

    proc mgetOrPut[A, B](t: var Table[A, B]; key: A; val: B): var B

  Retrieves value at `t[key]` or puts `val` if not present, either way returning a value which can be modified.

  Note that while the value returned is of type `var B`, it is easy to accidentally create a copy of the value at `t[key]`. Remember that seqs and strings are value types, and therefore cannot be copied into a separate variable for modification. See the example below.

  See also:

  - [] proc for retrieving a value of a key
  - hasKey proc
  - hasKeyOrPut proc
  - getOrDefault proc to return a default value (e.g. zero for int) if the key doesn't exist
  - getOrDefault proc to return a custom value if the key doesn't exist

  Example:

      var a = {'a': 5, 'b': 9}.toTable
      doAssert a.mgetOrPut('a', 99) == 5
      doAssert a.mgetOrPut('z', 99) == 99
      doAssert a == {'a': 5, 'b': 9, 'z': 99}.toTable

      # An example of accidentally creating a copy
      var t = initTable[int, seq[int]]()
      # In this example, we expect t[10] to be modified,
      # but it is not.
      var copiedSeq = t.mgetOrPut(10, @[10])
      copiedSeq.add(20)
      doAssert t[10] == @[10]
      # Correct
      t.mgetOrPut(25, @[25]).add(35)
      doAssert t[25] == @[25, 35]

  Source Edit

    proc newCountTable[A](initialSize = defaultInitialSize): CountTableRef[A]

  Creates a new ref count table that is empty.

  See also:

  - newCountTable proc for creating a `CountTableRef` from a collection
  - initCountTable proc for creating a `CountTable`
  Source Edit

    proc newCountTable[A](keys: openArray[A]): CountTableRef[A]

  Creates a new ref count table with every member of a container `keys` having a count of how many times it occurs in that container. Source Edit

    proc newOrderedTable[A, B](initialSize = defaultInitialSize): OrderedTableRef[A,
        B]

  Creates a new ordered ref hash table that is empty.

  See also:

  - newOrderedTable proc for creating an `OrderedTableRef` from a collection of `(key, value)` pairs
  - initOrderedTable proc for creating an `OrderedTable`

  Example:

      let
        a = newOrderedTable[int, string]()
        b = newOrderedTable[char, seq[int]]()

  Source Edit

    proc newOrderedTable[A, B](pairs: openArray[(A, B)]): OrderedTableRef[A, B]

  Creates a new ordered ref hash table that contains the given `pairs`.

  `pairs` is a container consisting of `(key, value)` tuples.

  See also:

  - newOrderedTable proc
  - toOrderedTable proc for an `OrderedTable` version

  Example:

      let a = [('a', 5), ('b', 9)]
      let b = newOrderedTable(a)
      assert b == {'a': 5, 'b': 9}.newOrderedTable

  Source Edit

    proc newTable[A, B](initialSize = defaultInitialSize): TableRef[A, B]

  Creates a new ref hash table that is empty.

  See also:

  - newTable proc for creating a `TableRef` from a collection of `(key, value)` pairs
  - initTable proc for creating a `Table`

  Example:

      let
        a = newTable[int, string]()
        b = newTable[char, seq[int]]()

  Source Edit

    proc newTable[A, B](pairs: openArray[(A, B)]): TableRef[A, B]

  Creates a new ref hash table that contains the given `pairs`.

  `pairs` is a container consisting of `(key, value)` tuples.

  See also:

  - newTable proc
  - toTable proc for a `Table` version

  Example:

      let a = [('a', 5), ('b', 9)]
      let b = newTable(a)
      assert b == {'a': 5, 'b': 9}.newTable

  Source Edit

    proc newTableFrom[A, B, C](collection: A; index: proc (x: B): C): TableRef[C, B]

  Index the collection with the proc provided. Source Edit

    proc pop[A, B](t: OrderedTableRef[A, B]; key: A; val: var B): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.

  See also:

  - del proc
  - clear proc to empty the whole table

  Example:

      var
        a = {'c': 5, 'b': 9, 'a': 13}.newOrderedTable
        i: int
      doAssert a.pop('b', i) == true
      doAssert a == {'c': 5, 'a': 13}.newOrderedTable
      doAssert i == 9
      i = 0
      doAssert a.pop('z', i) == false
      doAssert a == {'c': 5, 'a': 13}.newOrderedTable
      doAssert i == 0

  Source Edit

    proc pop[A, B](t: TableRef[A, B]; key: A; val: var B): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.
  Warning: If duplicate keys were added (via the now deprecated `add` proc), this may need to be called multiple times.

  See also:

  - del proc
  - clear proc to empty the whole table

  Example:

      var
        a = {'a': 5, 'b': 9, 'c': 13}.newTable
        i: int
      doAssert a.pop('b', i) == true
      doAssert a == {'a': 5, 'c': 13}.newTable
      doAssert i == 9
      i = 0
      doAssert a.pop('z', i) == false
      doAssert a == {'a': 5, 'c': 13}.newTable
      doAssert i == 0

  Source Edit

    proc pop[A, B](t: var OrderedTable[A, B]; key: A; val: var B): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.

  O(n) complexity.

  See also:

  - del proc
  - clear proc to empty the whole table

  Example:

      var
        a = {'c': 5, 'b': 9, 'a': 13}.toOrderedTable
        i: int
      doAssert a.pop('b', i) == true
      doAssert a == {'c': 5, 'a': 13}.toOrderedTable
      doAssert i == 9
      i = 0
      doAssert a.pop('z', i) == false
      doAssert a == {'c': 5, 'a': 13}.toOrderedTable
      doAssert i == 0

  Source Edit

    proc pop[A, B](t: var Table[A, B]; key: A; val: var B): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.
  Warning: If duplicate keys were added (via the now deprecated `add` proc), this may need to be called multiple times.

  See also:

  - del proc
  - clear proc to empty the whole table

  Example:

      var
        a = {'a': 5, 'b': 9, 'c': 13}.toTable
        i: int
      doAssert a.pop('b', i) == true
      doAssert a == {'a': 5, 'c': 13}.toTable
      doAssert i == 9
      i = 0
      doAssert a.pop('z', i) == false
      doAssert a == {'a': 5, 'c': 13}.toTable
      doAssert i == 0

  Source Edit

    proc pop[A](t: CountTableRef[A]; key: A; val: var int): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.

  See also:

  - del proc
  - clear proc to empty the whole table
  Source Edit

    proc pop[A](t: var CountTable[A]; key: A; val: var int): bool

  Deletes the `key` from the table. Returns `true`, if the `key` existed, and sets `val` to the mapping of the key. Otherwise, returns `false`, and the `val` is unchanged.

  See also:

  - del proc
  - clear proc to empty the whole table

  Example:

      var a = toCountTable("aabbbccccc")
      var i = 0
      assert a.pop('b', i)
      assert i == 3
      i = 99
      assert not a.pop('b', i)
      assert i == 99

  Source Edit

    proc smallest[A](t: CountTable[A]): tuple[key: A, val: int]

  Returns the `(key, value)` pair with the smallest `val`. Efficiency: O(n)

  See also:

  - largest proc
  Source Edit

    proc smallest[A](t: CountTableRef[A]): tuple[key: A, val: int]

  Returns the `(key, value)` pair with the smallest `val`. Efficiency: O(n)

  See also:

  - largest proc
  Source Edit

    proc sort[A, B](t: OrderedTableRef[A, B]; cmp: proc (x, y: (A, B)): int;
                    order = SortOrder.Ascending) {.effectsOf: cmp.}

  Sorts `t` according to the function `cmp`.

  This modifies the internal list that kept the insertion order, so insertion order is lost after this call but key lookup and insertions remain possible after `sort` (in contrast to the sort proc for count tables).

  Example:

      import std/[algorithm]
      var a = newOrderedTable[char, int]()
      for i, c in "cab":
        a[c] = 10*i
      doAssert a == {'c': 0, 'a': 10, 'b': 20}.newOrderedTable
      a.sort(system.cmp)
      doAssert a == {'a': 10, 'b': 20, 'c': 0}.newOrderedTable
      a.sort(system.cmp, order = SortOrder.Descending)
      doAssert a == {'c': 0, 'b': 20, 'a': 10}.newOrderedTable

  Source Edit

    proc sort[A, B](t: var OrderedTable[A, B]; cmp: proc (x, y: (A, B)): int;
                    order = SortOrder.Ascending) {.effectsOf: cmp.}

  Sorts `t` according to the function `cmp`.

  This modifies the internal list that kept the insertion order, so insertion order is lost after this call but key lookup and insertions remain possible after `sort` (in contrast to the sort proc for count tables).

  Example:

      import std/[algorithm]
      var a = initOrderedTable[char, int]()
      for i, c in "cab":
        a[c] = 10*i
      doAssert a == {'c': 0, 'a': 10, 'b': 20}.toOrderedTable
      a.sort(system.cmp)
      doAssert a == {'a': 10, 'b': 20, 'c': 0}.toOrderedTable
      a.sort(system.cmp, order = SortOrder.Descending)
      doAssert a == {'c': 0, 'b': 20, 'a': 10}.toOrderedTable

  Source Edit

    proc sort[A](t: CountTableRef[A]; order = SortOrder.Descending)

  Sorts the count table so that, by default, the entry with the highest counter comes first.

  This is destructive! You must not modify `t` afterwards!

  You can use the iterators pairs, keys, and values to iterate over `t` in the sorted order.

  Source Edit

    proc sort[A](t: var CountTable[A]; order = SortOrder.Descending)

  Sorts the count table so that, by default, the entry with the highest counter comes first.
  Warning: This is destructive! Once sorted, you must not modify `t` afterwards!

  You can use the iterators pairs, keys, and values to iterate over `t` in the sorted order.

  Example:

      import std/[algorithm, sequtils]
      var a = toCountTable("abracadabra")
      doAssert a == "aaaaabbrrcd".toCountTable
      a.sort()
      doAssert toSeq(a.values) == @[5, 2, 2, 1, 1]
      a.sort(SortOrder.Ascending)
      doAssert toSeq(a.values) == @[1, 1, 2, 2, 5]

  Source Edit

    proc take[A, B](t: TableRef[A, B]; key: A; val: var B): bool {.inline.}

  Alias for:
  - pop proc
  Source Edit

    proc take[A, B](t: var Table[A, B]; key: A; val: var B): bool {.inline.}

  Alias for:
  - pop proc
  Source Edit

    proc toCountTable[A](keys: openArray[A]): CountTable[A]

  Creates a new count table with every member of a container `keys` having a count of how many times it occurs in that container. Source Edit

    proc toOrderedTable[A, B](pairs: openArray[(A, B)]): OrderedTable[A, B]

  Creates a new ordered hash table that contains the given `pairs`.

  `pairs` is a container consisting of `(key, value)` tuples.

  See also:

  - initOrderedTable proc
  - newOrderedTable proc for an `OrderedTableRef` version

  Example:

      let a = [('a', 5), ('b', 9)]
      let b = toOrderedTable(a)
      assert b == {'a': 5, 'b': 9}.toOrderedTable

  Source Edit

    proc toTable[A, B](pairs: openArray[(A, B)]): Table[A, B]

  Creates a new hash table that contains the given `pairs`.

  `pairs` is a container consisting of `(key, value)` tuples.

  See also:

  - initTable proc
  - newTable proc for a `TableRef` version

  Example:

      let a = [('a', 5), ('b', 9)]
      let b = toTable(a)
      assert b == {'a': 5, 'b': 9}.toTable

  Source Edit

# Iterators

    iterator allValues[A, B](t: Table[A, B]; key: A): B {....deprecated: "Deprecated since v1.4; tables with duplicated keys are deprecated".}

  Deprecated: Deprecated since v1.4; tables with duplicated keys are deprecated

  Iterates over any value in the table `t` that belongs to the given `key`.

  Used if you have a table with duplicate keys (as a result of using add proc).

  Example:

      import std/[sequtils, algorithm]

      var a = {'a': 3, 'b': 5}.toTable
      for i in 1..3: a.add('z', 10*i)
      doAssert toSeq(a.pairs).sorted == @[('a', 3), ('b', 5), ('z', 10), ('z', 20), ('z', 30)]
      doAssert sorted(toSeq(a.allValues('z'))) == @[10, 20, 30]

  Source Edit

    iterator keys[A, B](t: OrderedTable[A, B]): lent A

  Iterates over any key in the table `t` in insertion order.

  See also:

  - pairs iterator
  - values iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toOrderedTable
      for k in a.keys:
        a[k].add(99)
      doAssert a == {'o': @[1, 5, 7, 9, 99],
                     'e': @[2, 4, 6, 8, 99]}.toOrderedTable

  Source Edit

    iterator keys[A, B](t: OrderedTableRef[A, B]): lent A

  Iterates over any key in the table `t` in insertion order.

  See also:

  - pairs iterator
  - values iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newOrderedTable
      for k in a.keys:
        a[k].add(99)
      doAssert a == {'o': @[1, 5, 7, 9, 99], 'e': @[2, 4, 6, 8,
          99]}.newOrderedTable

  Source Edit

    iterator keys[A, B](t: Table[A, B]): lent A

  Iterates over any key in the table `t`.

  See also:

  - pairs iterator
  - values iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toTable
      for k in a.keys:
        a[k].add(99)
      doAssert a == {'e': @[2, 4, 6, 8, 99], 'o': @[1, 5, 7, 9, 99]}.toTable

  Source Edit

    iterator keys[A, B](t: TableRef[A, B]): lent A

  Iterates over any key in the table `t`.

  See also:

  - pairs iterator
  - values iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newTable
      for k in a.keys:
        a[k].add(99)
      doAssert a == {'e': @[2, 4, 6, 8, 99], 'o': @[1, 5, 7, 9, 99]}.newTable

  Source Edit

    iterator keys[A](t: CountTable[A]): lent A

  Iterates over any key in the table `t`.

  See also:

  - pairs iterator
  - values iterator

  Example:

      var a = toCountTable("abracadabra")
      for k in keys(a):
        a[k] = 2
      doAssert a == toCountTable("aabbccddrr")

  Source Edit

    iterator keys[A](t: CountTableRef[A]): A

  Iterates over any key in the table `t`.

  See also:

  - pairs iterator
  - values iterator

  Example:

      let a = newCountTable("abracadabra")
      for k in keys(a):
        a[k] = 2
      doAssert a == newCountTable("aabbccddrr")

  Source Edit

    iterator mpairs[A, B](t: OrderedTableRef[A, B]): (A, var B)

  Iterates over any `(key, value)` pair in the table `t` in insertion order. The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newOrderedTable
      for k, v in a.mpairs:
        v.add(v[0] + 10)
      doAssert a == {'o': @[1, 5, 7, 9, 11],
                     'e': @[2, 4, 6, 8, 12]}.newOrderedTable

  Source Edit

    iterator mpairs[A, B](t: TableRef[A, B]): (A, var B)

  Iterates over any `(key, value)` pair in the table `t`. The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newTable
      for k, v in a.mpairs:
        v.add(v[0] + 10)
      doAssert a == {'e': @[2, 4, 6, 8, 12], 'o': @[1, 5, 7, 9, 11]}.newTable

  Source Edit

    iterator mpairs[A, B](t: var OrderedTable[A, B]): (A, var B)

  Iterates over any `(key, value)` pair in the table `t` (must be declared as `var`) in insertion order. The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toOrderedTable
      for k, v in a.mpairs:
        v.add(v[0] + 10)
      doAssert a == {'o': @[1, 5, 7, 9, 11],
                     'e': @[2, 4, 6, 8, 12]}.toOrderedTable

  Source Edit

    iterator mpairs[A, B](t: var Table[A, B]): (A, var B)

  Iterates over any `(key, value)` pair in the table `t` (must be declared as `var`). The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toTable
      for k, v in a.mpairs:
        v.add(v[0] + 10)
      doAssert a == {'e': @[2, 4, 6, 8, 12], 'o': @[1, 5, 7, 9, 11]}.toTable

  Source Edit

    iterator mpairs[A](t: CountTableRef[A]): (A, var int)

  Iterates over any `(key, value)` pair in the table `t`. The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      let a = newCountTable("abracadabra")
      for k, v in mpairs(a):
        v = 2
      doAssert a == newCountTable("aabbccddrr")

  Source Edit

    iterator mpairs[A](t: var CountTable[A]): (A, var int)

  Iterates over any `(key, value)` pair in the table `t` (must be declared as `var`). The values can be modified.

  See also:

  - pairs iterator
  - mvalues iterator

  Example:

      var a = toCountTable("abracadabra")
      for k, v in mpairs(a):
        v = 2
      doAssert a == toCountTable("aabbccddrr")

  Source Edit

    iterator mvalues[A, B](t: OrderedTableRef[A, B]): var B

  Iterates over any value in the table `t` in insertion order. The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newOrderedTable
      for v in a.mvalues:
        v.add(99)
      doAssert a == {'o': @[1, 5, 7, 9, 99],
                     'e': @[2, 4, 6, 8, 99]}.newOrderedTable

  Source Edit

    iterator mvalues[A, B](t: TableRef[A, B]): var B

  Iterates over any value in the table `t`. The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newTable
      for v in a.mvalues:
        v.add(99)
      doAssert a == {'e': @[2, 4, 6, 8, 99], 'o': @[1, 5, 7, 9, 99]}.newTable

  Source Edit

    iterator mvalues[A, B](t: var OrderedTable[A, B]): var B

  Iterates over any value in the table `t` (must be declared as `var`) in insertion order. The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toOrderedTable
      for v in a.mvalues:
        v.add(99)
      doAssert a == {'o': @[1, 5, 7, 9, 99],
                     'e': @[2, 4, 6, 8, 99]}.toOrderedTable

  Source Edit

    iterator mvalues[A, B](t: var Table[A, B]): var B

  Iterates over any value in the table `t` (must be declared as `var`). The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      var a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toTable
      for v in a.mvalues:
        v.add(99)
      doAssert a == {'e': @[2, 4, 6, 8, 99], 'o': @[1, 5, 7, 9, 99]}.toTable

  Source Edit

    iterator mvalues[A](t: CountTableRef[A]): var int

  Iterates over any value in the table `t`. The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      var a = newCountTable("abracadabra")
      for v in mvalues(a):
        v = 2
      doAssert a == newCountTable("aabbccddrr")

  Source Edit

    iterator mvalues[A](t: var CountTable[A]): var int

  Iterates over any value in the table `t` (must be declared as `var`). The values can be modified.

  See also:

  - mpairs iterator
  - values iterator

  Example:

      var a = toCountTable("abracadabra")
      for v in mvalues(a):
        v = 2
      doAssert a == toCountTable("aabbccddrr")

  Source Edit

    iterator pairs[A, B](t: OrderedTable[A, B]): (A, B)

  Iterates over any `(key, value)` pair in the table `t` in insertion order.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = {
        'o': [1, 5, 7, 9],
        'e': [2, 4, 6, 8]
        }.toOrderedTable

      for k, v in a.pairs:
        echo "key: ", k
        echo "value: ", v

      # key: o
      # value: [1, 5, 7, 9]
      # key: e
      # value: [2, 4, 6, 8]

  Source Edit

    iterator pairs[A, B](t: OrderedTableRef[A, B]): (A, B)

  Iterates over any `(key, value)` pair in the table `t` in insertion order.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = {
        'o': [1, 5, 7, 9],
        'e': [2, 4, 6, 8]
        }.newOrderedTable

      for k, v in a.pairs:
        echo "key: ", k
        echo "value: ", v

      # key: o
      # value: [1, 5, 7, 9]
      # key: e
      # value: [2, 4, 6, 8]

  Source Edit

    iterator pairs[A, B](t: Table[A, B]): (A, B)

  Iterates over any `(key, value)` pair in the table `t`.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = {
        'o': [1, 5, 7, 9],
        'e': [2, 4, 6, 8]
        }.toTable

      for k, v in a.pairs:
        echo "key: ", k
        echo "value: ", v

      # key: e
      # value: [2, 4, 6, 8]
      # key: o
      # value: [1, 5, 7, 9]

  Source Edit

    iterator pairs[A, B](t: TableRef[A, B]): (A, B)

  Iterates over any `(key, value)` pair in the table `t`.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = {
        'o': [1, 5, 7, 9],
        'e': [2, 4, 6, 8]
        }.newTable

      for k, v in a.pairs:
        echo "key: ", k
        echo "value: ", v

      # key: e
      # value: [2, 4, 6, 8]
      # key: o
      # value: [1, 5, 7, 9]

  Source Edit

    iterator pairs[A](t: CountTable[A]): (A, int)

  Iterates over any `(key, value)` pair in the table `t`.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = toCountTable("abracadabra")

      for k, v in pairs(a):
        echo "key: ", k
        echo "value: ", v

      # key: a
      # value: 5
      # key: b
      # value: 2
      # key: c
      # value: 1
      # key: d
      # value: 1
      # key: r
      # value: 2

  Source Edit

    iterator pairs[A](t: CountTableRef[A]): (A, int)

  Iterates over any `(key, value)` pair in the table `t`.

  See also:

  - mpairs iterator
  - keys iterator
  - values iterator

  Examples:

      let a = newCountTable("abracadabra")

      for k, v in pairs(a):
        echo "key: ", k
        echo "value: ", v

      # key: a
      # value: 5
      # key: b
      # value: 2
      # key: c
      # value: 1
      # key: d
      # value: 1
      # key: r
      # value: 2

  Source Edit

    iterator values[A, B](t: OrderedTable[A, B]): lent B

  Iterates over any value in the table `t` in insertion order.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toOrderedTable
      for v in a.values:
        doAssert v.len == 4

  Source Edit

    iterator values[A, B](t: OrderedTableRef[A, B]): lent B

  Iterates over any value in the table `t` in insertion order.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newOrderedTable
      for v in a.values:
        doAssert v.len == 4

  Source Edit

    iterator values[A, B](t: Table[A, B]): lent B

  Iterates over any value in the table `t`.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.toTable
      for v in a.values:
        doAssert v.len == 4

  Source Edit

    iterator values[A, B](t: TableRef[A, B]): lent B

  Iterates over any value in the table `t`.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = {
        'o': @[1, 5, 7, 9],
        'e': @[2, 4, 6, 8]
        }.newTable
      for v in a.values:
        doAssert v.len == 4

  Source Edit

    iterator values[A](t: CountTable[A]): int

  Iterates over any value in the table `t`.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = toCountTable("abracadabra")
      for v in values(a):
        assert v < 10

  Source Edit

    iterator values[A](t: CountTableRef[A]): int

  Iterates over any value in the table `t`.

  See also:

  - pairs iterator
  - keys iterator
  - mvalues iterator

  Example:

      let a = newCountTable("abracadabra")
      for v in values(a):
        assert v < 10

  Source Edit

# Templates

    template withValue[A, B](t: Table[A, B]; key: A; value, body1, body2: untyped)

  Retrieves the value at `t[key]` if it exists, assigns it to the variable `value` and executes `body`

  Example:

      type
        User = object
          name: string

      proc `=copy`(dest: var User, source: User) {.error.}

      proc exec(t: Table[int, User]) =
        t.withValue(1, value):
          assert value.name == "Hello"
        do:
          doAssert false

        var executedElseBranch = false
        t.withValue(521, value):
          doAssert false
        do:
          executedElseBranch = true
        assert executedElseBranch

      var t = initTable[int, User]()
      t[1] = User(name: "Hello")
      t.exec()

  Source Edit

    template withValue[A, B](t: Table[A, B]; key: A; value, body: untyped)

  Retrieves the value at `t[key]` if it exists, assigns it to the variable `value` and executes `body`

  Example:

      type
        User = object
          name: string

      proc `=copy`(dest: var User, source: User) {.error.}

      proc exec(t: Table[int, User]) =
        t.withValue(1, value):
          assert value.name == "Hello"

        t.withValue(521, value):
          doAssert false

      var t = initTable[int, User]()
      t[1] = User(name: "Hello")
      t.exec()

  Source Edit

    template withValue[A, B](t: var Table[A, B]; key: A;
                             value, body1, body2: untyped)

  Retrieves the value at `t[key]`.

  `value` can be modified in the scope of the `withValue` call.

  Example:

      type
        User = object
          name: string
          uid: int

      var t = initTable[int, User]()
      let u = User(name: "Hello", uid: 99)
      t[1] = u

      t.withValue(1, value):
        # block is executed only if `key` in `t`
        value.name = "Nim"
        value.uid = 1314

      t.withValue(521, value):
        doAssert false
      do:
        # block is executed when `key` not in `t`
        t[1314] = User(name: "exist", uid: 521)

      assert t[1].name == "Nim"
      assert t[1].uid == 1314
      assert t[1314].name == "exist"
      assert t[1314].uid == 521

  Source Edit

    template withValue[A, B](t: var Table[A, B]; key: A; value, body: untyped)

  Retrieves the value at `t[key]`.

  `value` can be modified in the scope of the `withValue` call.

  Example:

      type
        User = object
          name: string
          uid: int

      var t = initTable[int, User]()
      let u = User(name: "Hello", uid: 99)
      t[1] = u

      t.withValue(1, value):
        # block is executed only if `key` in `t`
        value.name = "Nim"
        value.uid = 1314

      t.withValue(2, value):
        value.name = "No"
        value.uid = 521

      assert t[1].name == "Nim"
      assert t[1].uid == 1314

  Source Edit