How do I use a Set for unique values in EK9?
← Collections and Data Structures · Ref: Q1365
Set of type T is a built-in collection of UNIQUE values. Adding a value that is already present has no effect, so it is the natural tool for de-duplication and fast membership testing.
INSERTION-ORDERED
Unlike a hash set in some languages, an EK9 Set is INSERTION-ORDERED (backed by a linked hash set, just like Dict). Iterating a Set yields values in the order they were first added, which is deterministic and reproducible across runs and JVMs - so output and tests stay stable. Do not rely on any other order.
CREATING AND ADDING
seen <- Set() of String seen += "apple" seen += "banana" seen += "apple" // duplicate - no effect
Uniqueness is by VALUE, using the element type's == and #? (hashcode) operators - the same mechanism that makes a value a valid Dict key.
MEMBERSHIP, SIZE, ITERATION
found <- seen contains "banana" count <- seen.length() // reflects the unique count for item in seen // first-insertion order stdout.println(item)
A Set is always set when created; an empty Set is a valid value, not unset.
UNION AND DIFFERENCE
combined <- setA + setB // union removed <- setA - setB // difference
These also have in-place forms (+=, -=) and merge (:~:).
WHY NOT DICT OF (T, BOOLEAN)?
Before Set, membership was faked with Dict of (T, Boolean). Set says what you mean, iterates in insertion order, and its length is the unique count directly.
List and Dict are the other core collections. Use 'ek9 -h Set' for the full API.
Example
defines module qa.set.unique defines program SetUnique() stdout <- Stdout() //A Set holds unique values; a duplicate add has no effect. seen <- Set() of String seen += "apple" seen += "banana" seen += "apple" count <- seen.length() stdout.println(`unique count: ${count}`) found <- seen contains "banana" stdout.println(`contains banana: ${found}`) //Iteration is in first-insertion order (deterministic). for item in seen stdout.println(item) //Union with another Set. other <- Set() of String other += "cherry" other += "date" combined <- seen + other stdout.println(`union count: ${combined.length()}`)
Common mistakes
E05030 — Set (like the other built-in generic collections) is CLOSED - it cannot be extended (E05030: not open to be extended). Extending a collection mixes collection mechanics with application logic. Use composition/delegation instead: hold a 'Set of String' as a field and expose the operations you need.
Incorrect:
MyThing extends Set of String
Correct:
MyThing items as Set of String
Other ways to ask this
- How do I remove duplicates in EK9?
- Is there a Set type in EK9?
- How do I test membership efficiently?
- How do I get the union or difference of two collections?
Coming from another language?
Java: HashSet (unordered) / LinkedHashSet (insertion order). Python: set (unordered) - EK9 differs by being insertion-ordered. Go: map[T]struct{} idiom. Rust: HashSet / IndexSet. EK9: Set of type T, insertion-ordered by design (like Dict), value-based uniqueness via == and #?, with +/-/+=/-=/contains/length and for-in iteration.
Keywords: set, dedup, distinct, order, duplicate, membership, collection, hashset, union, unique, insertion, difference, contains