with one click
tables
Nim's hash table module for key-value storage
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Nim's hash table module for key-value storage
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Nim testing conventions, unittest framework, and C++ compatibility patterns
Nim bindings to libtorch for tensor operations with high-level sugar
Nim type system patterns and pitfalls
Common import patterns and pitfalls for the Tattletale Nim project
Regex functionality in Nim including std/re, std/nre wrappers around PCRE, and the pure Nim nim-regex alternative with linear-time matching guarantees
Nim to Python interoperability including nimpy for calling Python from Nim and exporting Nim to Python, nimporter for packaging Nim modules as Python packages, and cffi/ctypes for calling Nim from Python
| name | tables |
| description | Nim's hash table module for key-value storage |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"nim-developers","use-case":"data-structures"} |
tables ModuleThe tables module provides hash table implementations for key-value storage in Nim.
Table[A, B] - Standard hash table (value semantics, copies on assignment)TableRef[A, B] - Reference-based hash table (shared on assignment)OrderedTable[A, B] - Preserves insertion orderCountTable[A] - Maps keys to occurrence countsimport std/tables
# Create empty table
var t = initTable[string, int]()
t["key"] = 42
# Create from pairs literal
let t2 = {"a": 1, "b": 2}.toTable
# TableRef for ref semantics (shared state)
let ref_t = newTable[string, int]()
ref_t["key"] = 42
# Insert or update
t["key"] = 42
# Access (raises KeyError if missing)
let val = t["key"]
# Check if key exists
if t.hasKey("key"):
discard
# Get with default value
let val = t.getOrDefault("key", 0)
# Atomic check-and-set
if t.hasKeyOrPut("key", defaultValue):
# key already existed
else:
# key was just inserted
# Get or modify
discard t.mgetOrPut("key", defaultValue)
t["key"] = t["key"] + 1
# Delete (does nothing if missing)
t.del("key")
# Length
echo t.len
Use pairs, keys, and values iterators to traverse tables:
for k, v in t.pairs:
echo "key: ", k, " value: ", v
for k in t.keys:
echo "key: ", k
for v in t.values:
echo "value: ", v
# For mutable tables, use mpairs/mvalues to modify in place
for k, v in t.mpairs:
v = v + 1
Preserves insertion order (unlike regular Table):
import std/tables
var ot = initOrderedTable[string, int]()
ot["z"] = 1
ot["a"] = 2
ot["m"] = 3
# Iteration follows insertion order: z, a, m
for k, v in ot.pairs:
echo k, " -> ", v
Counts occurrences (useful for frequency analysis):
import std/tables
# Create from sequence
var ct = toCountTable("abracadabra")
# Result: {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
# Increment count
ct.inc('x')
ct.inc('y', 5) # increment by 5
# Get count (returns 0 if missing)
echo ct['a'] # 5
# Sort by frequency
ct.sort() # descending by default
template withValue*[A, B](t: var Table[A, B], key: A, value, body: untyped) =
## Retrieves value at t[key] if it exists, binds to `value`
mixin rawGet
var hc: Hash
var index = rawGet(t, key, hc)
let hasKey = index >= 0
if hasKey:
var value {.inject.} = addr(t.data[index].val)
body
# Usage
t.withValue("mykey", val):
echo "Found: ", val
do:
echo "Key not found"
var result = ct1
for k, v in ct2:
result.inc(k, v)
| Feature | Table | TableRef |
|---|---|---|
| Assignment | Copies entire table | Shares reference |
| Memory | Each copy is independent | All refs point to same data |
| Use when | Isolation needed | Shared mutable state |
hash proc for keys - works with int, string, and custom types with defined hash procpairs iterator returns (key, value) tuples - use toSeq() to convert to seqOrderedTable uses more memory but preserves insertion orderCountTable uses zero as sentinel, so count of 0 means "empty slot"