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 but remembers insertion order,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 != bOn 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
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 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 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 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}"
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
CountTable[A] = object
Hash table that counts the number of each key.
For creating an empty CountTable, use initCountTable proc.
Source EditCountTableRef[A] = ref CountTable[A]
Ref version of CountTable.
For creating a new empty CountTableRef, use newCountTable proc.
Source EditOrderedTable[A; B] = object
Hash table that remembers insertion order.
For creating an empty OrderedTable, use initOrderedTable proc.
Source EditOrderedTableRef[A; B] = ref OrderedTable[A, B]
Ref version of OrderedTable.
For creating a new empty OrderedTableRef, use newOrderedTable proc.
Source EditTable[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 EditTableRef[A; B] = ref Table[A, B]
Ref version of Table.
For creating a new empty TableRef, use newTable proc.
Source Editproc `$`[A, B](t: OrderedTable[A, B]): string
$ operator for ordered hash tables. Used internally when calling echo on a table. Source Edit proc `$`[A, B](t: OrderedTableRef[A, B]): string
$ operator for hash tables. Used internally when calling echo on a table. Source Edit proc `$`[A, B](t: Table[A, B]): string
$ operator for hash tables. Used internally when calling echo on a table. Source Edit proc `$`[A, B](t: TableRef[A, B]): string
$ operator for hash tables. Used internally when calling echo on a table. Source Edit proc `==`[A, B](s, t: OrderedTable[A, B]): bool
== 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
== 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
== 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
== 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, 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:
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:
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:
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:
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:
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:
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:
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:
proc `[]=`[A, B](t: OrderedTableRef[A, B]; key: A; val: sink B)
Inserts a (key, value) pair into t.
See also:
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:
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:
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:
Example:
var a = initTable[char, int]()
a['x'] = 7
a['y'] = 33
doAssert a == {'x': 7, 'y': 33}.toTable 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 `[]=`".}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 Editproc add[A, B](t: TableRef[A, B]; key: A; val: sink B) {....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 Editproc 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 `[]=`".}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 Editproc 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 `[]=`".}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 Editproc clear[A, B](t: OrderedTableRef[A, B])
Resets the table so that it is empty.
See also:
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:
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:
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:
Example:
var a = {'a': 5, 'b': 9, 'c': 13}.toTable
doAssert len(a) == 3
clear(a)
doAssert len(a) == 0 Source Edit proc contains[A, B](t: OrderedTable[A, B]; key: A): bool
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
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
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
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
in operator. Source Edit proc contains[A](t: CountTableRef[A]; key: A): bool
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:
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)
key from hash table t. Does nothing if the key does not exist.add proc), this may need to be called multiple times.See also:
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:
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)
key from hash table t. Does nothing if the key does not exist.add proc), this may need to be called multiple times.See also:
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:
proc del[A](t: var CountTable[A]; key: A)
Deletes key from table t. Does nothing if the key does not exist.
See also:
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:
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; default: B): B
Retrieves the value at t[key] if key is in t. Otherwise, default is returned.
See also:
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:
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; default: B): B
Retrieves the value at t[key] if key is in t. Otherwise, default is returned.
See also:
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:
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; default: B): B
Retrieves the value at t[key] if key is in t. Otherwise, default is returned.
See also:
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:
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; default: B): B
Retrieves the value at t[key] if key is in t. Otherwise, default is returned.
See also:
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; default: int = 0): int
Retrieves the value at t[key] if key is in t. Otherwise, the integer value of default is returned.
See also:
proc getOrDefault[A](t: CountTableRef[A]; key: A; default: int): int
Retrieves the value at t[key] if key is in t. Otherwise, the integer value of default is returned.
See also:
proc hasKey[A, B](t: OrderedTable[A, B]; key: A): bool
Returns true if key is in the table t.
See also:
in operatorExample:
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:
in operatorExample:
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:
in operatorExample:
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:
in operatorExample:
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:
in operatorproc hasKey[A](t: CountTableRef[A]; key: A): bool
Returns true if key is in the table t.
See also:
in operatorproc 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:
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:
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:
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:
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 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:
CountTableRef
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:
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:
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:
Source Editproc len[A, B](t: OrderedTable[A, B]): int {.inline.}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.}t. Example:
let a = {'a': 5, 'b': 9}.newOrderedTable
doAssert len(a) == 2 Source Edit proc len[A, B](t: Table[A, B]): int
t. Example:
let a = {'a': 5, 'b': 9}.toTable
doAssert len(a) == 2 Source Edit proc mgetOrPut[A, B](t: OrderedTableRef[A, B]; key: A): var B
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:
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
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:
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
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:
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
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:
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:
CountTableRef from a collectionCountTable
proc newOrderedTable[A, B](initialSize = defaultInitialSize): OrderedTableRef[A,
B]Creates a new ordered ref hash table that is empty.
See also:
OrderedTableRef from a collection of (key, value) pairsOrderedTable
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:
OrderedTable versionExample:
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:
TableRef from a collection of (key, value) pairsTable
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:
Table versionExample:
let a = [('a', 5), ('b', 9)]
let b = newTable(a)
assert b == {'a': 5, 'b': 9}.newTable 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:
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
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.add proc), this may need to be called multiple times.See also:
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:
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
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.add proc), this may need to be called multiple times.See also:
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:
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:
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:
Source Editproc 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.
proc sort[A](t: var CountTable[A]; order = SortOrder.Descending)
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 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:
OrderedTableRef versionExample:
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:
TableRef versionExample:
let a = [('a', 5), ('b', 9)]
let b = toTable(a)
assert b == {'a': 5, 'b': 9}.toTable Source Edit iterator allValues[A, B](t: Table[A, B]; key: A): B {....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:
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:
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:
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:
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:
Example:
var a = toCountTable("abracadabra")
for k in keys(a):
a[k] = 2
doAssert a == toCountTable("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:
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:
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:
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:
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:
Example:
let a = newCountTable("abracadabra")
for k, v in mpairs(a):
v = 2
doAssert a == newCountTable("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:
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:
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:
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:
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:
Example:
var a = newCountTable("abracadabra")
for v in mvalues(a):
v = 2
doAssert a == newCountTable("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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
Example:
let a = toCountTable("abracadabra")
for v in values(a):
assert v < 10 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
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/tables.html