0
# Map and Set Operations
1
2
Specialized operations for ES6 Map and Set data structures. These operations provide type-safe ways to add and remove entries while maintaining immutability.
3
4
## Capabilities
5
6
### Add Operation
7
8
Adds entries to a Map or Set. For Maps, provide key-value pairs. For Sets, provide values to add.
9
10
```typescript { .api }
11
/**
12
* Add entries to a Map or Set
13
* For Map: Array of [key, value] pairs
14
* For Set: Array of values to add
15
* @param values - Entries to add
16
* @returns New Map or Set with added entries
17
*/
18
{ $add: ReadonlyArray<[K, V]> | ReadonlyArray<T> }
19
```
20
21
**Usage Examples:**
22
23
```typescript
24
import update from "immutability-helper";
25
26
// Add to Map
27
const userMap = new Map([
28
['alice', { age: 25, role: 'user' }],
29
['bob', { age: 30, role: 'admin' }]
30
]);
31
32
const updatedMap = update(userMap, {
33
$add: [
34
['charlie', { age: 28, role: 'user' }],
35
['diana', { age: 32, role: 'admin' }]
36
]
37
});
38
// Result: Map with 4 entries including charlie and diana
39
40
// Update existing Map entry
41
const modified = update(userMap, {
42
$add: [['alice', { age: 26, role: 'admin' }]]
43
});
44
// Result: alice's entry is updated with new values
45
46
// Add to Set
47
const tagSet = new Set(['frontend', 'javascript']);
48
const updatedSet = update(tagSet, {
49
$add: ['typescript', 'react']
50
});
51
// Result: Set(['frontend', 'javascript', 'typescript', 'react'])
52
53
// Nested Map operation
54
const data = {
55
users: new Map([['alice', { active: true }]]),
56
config: { theme: 'dark' }
57
};
58
const result = update(data, {
59
users: { $add: [['bob', { active: false }]] }
60
});
61
// Result: data.users now has both alice and bob
62
```
63
64
### Remove Operation
65
66
Removes entries from a Map or Set by key (for Maps) or value (for Sets).
67
68
```typescript { .api }
69
/**
70
* Remove entries from a Map or Set
71
* @param keys - Keys (for Map) or values (for Set) to remove
72
* @returns New Map or Set with specified entries removed
73
*/
74
{ $remove: ReadonlyArray<K> }
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
import update from "immutability-helper";
81
82
// Remove from Map
83
const userMap = new Map([
84
['alice', { age: 25 }],
85
['bob', { age: 30 }],
86
['charlie', { age: 28 }]
87
]);
88
89
const filtered = update(userMap, { $remove: ['bob', 'charlie'] });
90
// Result: Map with only alice entry
91
92
// Remove from Set
93
const tagSet = new Set(['frontend', 'backend', 'mobile', 'web']);
94
const reduced = update(tagSet, { $remove: ['mobile', 'backend'] });
95
// Result: Set(['frontend', 'web'])
96
97
// Remove non-existent entries (no effect)
98
const unchanged = update(userMap, { $remove: ['nonexistent'] });
99
// Result: Same Map (reference preserved if no changes)
100
101
// Nested Set operation
102
const data = {
103
tags: new Set(['js', 'ts', 'react', 'vue']),
104
meta: { count: 4 }
105
};
106
const result = update(data, {
107
tags: { $remove: ['vue'] }
108
});
109
// Result: data.tags = Set(['js', 'ts', 'react'])
110
```
111
112
## Complex Examples
113
114
```typescript
115
import update from "immutability-helper";
116
117
// Working with nested Maps
118
const cache = new Map([
119
['user:1', { name: 'Alice', permissions: new Set(['read', 'write']) }],
120
['user:2', { name: 'Bob', permissions: new Set(['read']) }]
121
]);
122
123
// Add permission to nested Set
124
const updated = update(cache, {
125
$add: [[
126
'user:2',
127
{
128
name: 'Bob',
129
permissions: update(
130
cache.get('user:2')?.permissions || new Set(),
131
{ $add: ['write', 'admin'] }
132
)
133
}
134
]]
135
});
136
137
// Multiple operations on same Map
138
const multiOp = update(userMap, {
139
$add: [['newUser', { age: 35 }]],
140
// Note: Cannot combine $add and $remove in same spec
141
// Use separate update calls or nested structure
142
});
143
144
// Correct way to add and remove in sequence
145
const sequential = update(
146
update(userMap, { $add: [['newUser', { age: 35 }]] }),
147
{ $remove: ['oldUser'] }
148
);
149
```
150
151
## Error Handling
152
153
Map and Set operations validate their inputs and throw descriptive errors:
154
155
- `$add` and `$remove` can only be used on Map or Set targets
156
- `$add` requires the spec value to be an array
157
- `$remove` requires the spec value to be an array
158
- For Maps, `$add` values must be `[key, value]` pairs
159
160
```typescript
161
// These will throw errors:
162
update({}, { $add: [['key', 'value']] }); // Target must be Map or Set
163
update(new Map(), { $add: 'value' }); // Spec must be array
164
update(new Set(), { $remove: 'value' }); // Spec must be array
165
```
166
167
## Performance Notes
168
169
- Operations preserve reference equality when no changes occur
170
- `$add` only creates a new Map/Set if values are actually different
171
- `$remove` only creates a new Map/Set if keys/values actually exist
172
- For Maps, existing entries are compared by value for change detection
173
- For Sets, duplicate values in `$add` are handled naturally (Sets ignore duplicates)
174
- Uses shallow copying of the Map/Set structure for optimal performance