| name | js-map-of-sets |
| description | Use the MapOfSets data structure when you need a Map that stores multiple unique values per key (a Map<K, Set<V>>). Handles adding, removing, querying, and iterating over grouped unique values without manual Set management. Use when the user needs to group items by key without duplicates, implement a multimap, track relationships like tags-to-items or events-to-listeners, or replace a plain Map<K, T[]> where uniqueness matters. |
| license | MIT |
| metadata | {"author":"burdiuz","package":"@actualwave/map-of-sets"} |
Overview
MapOfSets wraps a Map<K, Set<V>> and manages Set creation/cleanup automatically. Each key maps to a deduplicated set of values. When the last value under a key is removed, the key is also removed.
Installation
npm install @actualwave/map-of-sets
Basic usage
import MapOfSets, { createMapOfSets } from '@actualwave/map-of-sets';
const map = new MapOfSets<string, number>();
const map2 = createMapOfSets<string, number>();
map.add('even', 2);
map.add('even', 4);
map.add('even', 2);
map.has('even');
map.hasValue('even', 4);
map.get('even');
map.list('even');
API
has(key: K): boolean
hasValue(key: K, value: V): boolean
get(key: K): Set<V> | undefined
list(key: K): V[]
add(key: K, value: V): void
set(key: K, values: Set<V> | V[]): void
remove(key: K): void
removeValue(key: K, value: V): void
forEach(callback: (value: V, key: K, map: MapOfSets<K, V>) => void): void
eachValue(key: K, callback: (value: V, key: K, map: MapOfSets<K, V>) => void): void
clone(): MapOfSets<K, V>
Common patterns
Accumulate items by category:
const byTag = new MapOfSets<string, string>();
items.forEach(item => item.tags.forEach(tag => byTag.add(tag, item.id)));
Remove a relationship and check if the key is still active:
listeners.removeValue(event, handler);
if (!listeners.has(event)) cleanup(event);
Snapshot and restore:
const snapshot = map.clone();
Edge cases
set(key, []) and set(key, new Set()) both remove the key entirely.
removeValue on a missing key or missing value is a safe no-op.
forEach and eachValue do nothing on an empty map or missing key.
clone produces independent copies โ mutations to either side do not affect the other.