How do I iterate over Dict entries safely without worrying about missing keys?
← Safe Value Access · Ref: Q167
EK9 Dicts provide three iteration approaches: for-in over entries, .keys() iterator, and .values() iterator. All are safe because every yielded item is guaranteed to be set.
FOR-IN OVER ENTRIES
The simplest and most common pattern:
for entry in dict stdout.println(`${entry.key()}: ${entry.value()}`)
Each entry is a DictEntry with .key() and .value() accessors.
KEYS ITERATOR
Iterate over just the keys:
keyIter <- dict.keys() while keyIter? stdout.println(keyIter.next())
VALUES ITERATOR
Iterate over just the values:
valIter <- dict.values() while valIter? stdout.println($valIter.next())
STREAM PIPELINE
Use cat with a Dict for stream processing:
cat dict | map with entryToString | collect as List of String
Streams over DictEntry items.
See Q46 for Dict basics. See Q90 for Dict operations including keys/values. See Q89 for stream pipelines.
See Q46 for dict. See Q166 for consistent safe pattern.
Example
defines module qa.safeaccess.dictiteration defines function entryToString() as pure -> entry as DictEntry of (String, Integer) <- rtn as String: `${entry.key()} = ${entry.value()}` defines program DictIterationDemo() stdout <- Stdout() scores <- {"Alice": 95, "Bob": 87, "Charlie": 92} // === FOR-IN OVER ENTRIES === stdout.println("All entries:") for entry in scores stdout.println(` ${entry.key()}: ${entry.value()}`) // === KEYS ITERATOR === stdout.println("Keys:") keyIter <- scores.keys() while keyIter? stdout.println(` ${keyIter.next()}`) // === VALUES ITERATOR === stdout.println("Values:") valIter <- scores.values() while valIter? stdout.println(` ${valIter.next()}`) // === STREAM PIPELINE === formatted <- cat scores | map with entryToString | collect as List of String stdout.println(`Formatted: ${formatted}`) // === SAFE: EMPTY DICT ITERATION === emptyDict <- Dict() of (String, Integer) for entry in emptyDict stdout.println("Should not print") stdout.println("Empty dict iteration completed safely")
Common mistakes
E06020 — DictEntry requires two type parameters (key and value types). Providing only one triggers E06020 — incorrect number of parameters supplied. Use DictEntry of (KeyType, ValueType). See ek9 -h E06020 for details.
Incorrect:
-> entry as DictEntry of String
Correct:
-> entry as DictEntry of (String, Integer)
Other ways to ask this
- How do I loop over all key-value pairs in an EK9 Dict?
- How do I use for-in with a Dict in EK9?
- How do I iterate over Dict keys and values separately in EK9?
Coming from another language?
Java: map.entrySet().forEach(), map.keySet(), map.values(). Python: for k, v in dict.items(), dict.keys(), dict.values(). Rust: for (k, v) in map.iter(). Go: for k, v := range m. JavaScript: Object.entries(), Object.keys(), Object.values(). EK9: for entry in dict yields DictEntry, .keys()/.values() return iterators, cat dict for stream pipelines.
Keywords: null-safe, values, access, keys, dict, guard, loop, safe, DictEntry, stream, for, entries, iterate