0
# Array Operations
1
2
Methods for working with immutable arrays including functional operations, transformations, and element manipulation.
3
4
## Capabilities
5
6
### flatMap
7
8
Maps over array elements and flattens the results, similar to `map` followed by `flatten`.
9
10
```javascript { .api }
11
/**
12
* Maps and flattens array elements
13
* @param {Array} array - Source array to process
14
* @param {Function} iterator - Function that processes each element and returns a value or array
15
* @returns {Array} New immutable array with mapped and flattened results
16
*/
17
function flatMap(array, iterator);
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
const Immutable = require("seamless-immutable");
24
25
const array = Immutable(["here", "we", "go"]);
26
const repeated = array.flatMap(function(str) {
27
return [str, str, str];
28
});
29
// Result: ["here", "here", "here", "we", "we", "we", "go", "go", "go"]
30
31
// Filter out numbers by returning empty arrays
32
const mixed = Immutable(["drop the numbers!", 3, 2, 1, 0, null, undefined]);
33
const filtered = mixed.flatMap(function(value) {
34
if (typeof value === "number") {
35
return []; // Empty array removes the element
36
} else {
37
return value; // Non-arrays are treated as single elements
38
}
39
});
40
// Result: ["drop the numbers!", null, undefined]
41
42
// Split strings into characters
43
const words = Immutable(["hello", "world"]);
44
const chars = words.flatMap(word => word.split(''));
45
// Result: ["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]
46
```
47
48
### asObject
49
50
Converts an array to an object using key-value pairs, either from a provided iterator or assuming the array contains pairs.
51
52
```javascript { .api }
53
/**
54
* Convert array to object using key-value pairs
55
* @param {Array} array - Source array to convert
56
* @param {Function} [iterator] - Function that returns [key, value] pairs for each element
57
* @returns {Object} New immutable object created from the array
58
*/
59
function asObject(array, iterator);
60
```
61
62
**Usage Examples:**
63
64
```javascript
65
const Immutable = require("seamless-immutable");
66
67
// With iterator function
68
const array = Immutable(["hey", "you"]);
69
const obj = array.asObject(function(str) {
70
return [str, str.toUpperCase()];
71
});
72
// Result: {hey: "HEY", you: "YOU"}
73
74
// Array already contains key-value pairs
75
const pairs = Immutable([["name", "Alice"], ["age", 30]]);
76
const person = pairs.asObject();
77
// Result: {name: "Alice", age: 30}
78
79
// Using with objects to extract keys
80
const users = Immutable([
81
{id: 1, name: "Alice"},
82
{id: 2, name: "Bob"}
83
]);
84
const usersById = users.asObject(user => [user.id, user]);
85
// Result: {1: {id: 1, name: "Alice"}, 2: {id: 2, name: "Bob"}}
86
87
// Iterator receives index as second parameter
88
const indexed = Immutable(["a", "b", "c"]).asObject((value, index) => [index, value]);
89
// Result: {0: "a", 1: "b", 2: "c"}
90
```
91
92
### set (Array-specific)
93
94
Sets an element at a specific index in an array.
95
96
```javascript { .api }
97
/**
98
* Set element at specific index in an array
99
* @param {Array} array - Source array
100
* @param {number} idx - Index to set (can be beyond current length)
101
* @param {*} value - Value to set at the index
102
* @param {Object} [config] - Configuration options
103
* @param {boolean} [config.deep] - Deep merge if setting an object value
104
* @returns {Array} New immutable array with element set
105
*/
106
function set(array, idx, value, config);
107
```
108
109
**Usage Examples:**
110
111
```javascript
112
const Immutable = require("seamless-immutable");
113
114
const arr = Immutable([1, 2, 3]);
115
116
// Set existing index
117
const updated = arr.set(1, 99);
118
// Result: [1, 99, 3]
119
120
// Set beyond current length - fills with undefined
121
const extended = arr.set(5, "new");
122
// Result: [1, 2, 3, undefined, undefined, "new"]
123
124
// Deep merge when setting object values
125
const objArr = Immutable([{name: "Alice"}, {name: "Bob"}]);
126
const merged = objArr.set(0, {age: 30}, {deep: true});
127
// Result: [{name: "Alice", age: 30}, {name: "Bob"}]
128
129
// Using static method
130
const staticSet = Immutable.set(arr, 2, "replaced");
131
// Result: [1, 2, "replaced"]
132
```
133
134
### asMutable (Array-specific)
135
136
Converts an immutable array to a mutable copy.
137
138
```javascript { .api }
139
/**
140
* Convert immutable array to mutable copy
141
* @param {Array} array - Immutable array to convert
142
* @param {Object} [options] - Conversion options
143
* @param {boolean} [options.deep] - Recursively convert nested immutable structures
144
* @returns {Array} Mutable copy of the array
145
*/
146
function asMutable(array, options);
147
```
148
149
**Usage Examples:**
150
151
```javascript
152
const Immutable = require("seamless-immutable");
153
154
const array = Immutable(["hello", "world"]);
155
const mutableArray = array.asMutable();
156
157
// Now can use mutating methods
158
mutableArray.push("!!!");
159
console.log(mutableArray); // ["hello", "world", "!!!"]
160
161
// Deep conversion for nested structures
162
const nested = Immutable([
163
{name: "Alice", hobbies: ["reading"]},
164
{name: "Bob", hobbies: ["coding"]}
165
]);
166
167
const shallowMutable = nested.asMutable();
168
// shallowMutable[0].name = "Charlie"; // Would still throw - nested objects still immutable
169
170
const deepMutable = nested.asMutable({deep: true});
171
deepMutable[0].name = "Charlie"; // Works - all nested structures are now mutable
172
deepMutable[0].hobbies.push("gaming"); // Also works
173
```
174
175
## Enhanced Standard Array Methods
176
177
All standard non-mutating array methods are enhanced to return immutable arrays:
178
179
### map, filter, slice, concat
180
181
```javascript { .api }
182
/**
183
* Enhanced array methods that return immutable results
184
*/
185
function map(callback, thisArg);
186
function filter(callback, thisArg);
187
function slice(start, end);
188
function concat(...arrays);
189
function reduce(callback, initialValue);
190
function reduceRight(callback, initialValue);
191
```
192
193
**Usage Examples:**
194
195
```javascript
196
const Immutable = require("seamless-immutable");
197
198
const numbers = Immutable([1, 2, 3, 4, 5]);
199
200
// All return immutable arrays
201
const doubled = numbers.map(n => n * 2);
202
const evens = numbers.filter(n => n % 2 === 0);
203
const firstThree = numbers.slice(0, 3);
204
const extended = numbers.concat([6, 7, 8]);
205
206
console.log(Immutable.isImmutable(doubled)); // true
207
console.log(Immutable.isImmutable(evens)); // true
208
console.log(Immutable.isImmutable(firstThree)); // true
209
console.log(Immutable.isImmutable(extended)); // true
210
211
// Chaining works as expected
212
const result = numbers
213
.map(n => n * 2)
214
.filter(n => n > 4)
215
.slice(0, 2);
216
// Result: [6, 8] (immutable)
217
```
218
219
### keys
220
221
Returns an immutable result for object keys.
222
223
```javascript { .api }
224
/**
225
* Get array indices as an immutable array
226
* @returns {Array} Immutable array of indices
227
*/
228
function keys();
229
```
230
231
## Banned Mutating Methods
232
233
These methods throw `ImmutableError` when called on immutable arrays:
234
235
```javascript { .api }
236
// These methods throw ImmutableError:
237
function push(...elements); // Use concat() instead
238
function pop(); // Use slice(0, -1) instead
239
function shift(); // Use slice(1) instead
240
function unshift(...elements); // Use concat(newElements, array) instead
241
function splice(start, deleteCount, ...items); // Use slice() and concat() instead
242
function sort(compareFn); // Use slice().sort() on mutable copy instead
243
function reverse(); // Use slice().reverse() on mutable copy instead
244
```
245
246
**Alternative Patterns:**
247
248
```javascript
249
const Immutable = require("seamless-immutable");
250
const arr = Immutable([1, 2, 3]);
251
252
// Instead of mutating methods, use immutable alternatives:
253
254
// Instead of push(4)
255
const withFour = arr.concat([4]);
256
257
// Instead of pop()
258
const withoutLast = arr.slice(0, -1);
259
260
// Instead of shift()
261
const withoutFirst = arr.slice(1);
262
263
// Instead of unshift(0)
264
const withZero = [0].concat(arr);
265
266
// Instead of sort()
267
const sorted = arr.asMutable().sort(); // Convert to mutable first
268
// Or: const sorted = Immutable(arr.slice().sort());
269
270
// Instead of reverse()
271
const reversed = Immutable(arr.slice().reverse());
272
```
273
274
## Instance vs Static Methods
275
276
All array methods are available in both instance and static forms:
277
278
```javascript
279
const Immutable = require("seamless-immutable");
280
const arr = Immutable([1, 2, 3]);
281
282
// Instance methods (default API)
283
const mapped1 = arr.flatMap(x => [x, x]);
284
const obj1 = arr.asObject((val, idx) => [idx, val]);
285
const updated1 = arr.set(1, 99);
286
287
// Static methods (static API)
288
const ImmutableS = require("seamless-immutable").static;
289
const mapped2 = ImmutableS.flatMap(arr, x => [x, x]);
290
const obj2 = ImmutableS.asObject(arr, (val, idx) => [idx, val]);
291
const updated2 = ImmutableS.set(arr, 1, 99);
292
```
293
294
The static API is recommended when you want to avoid method name pollution or potential conflicts with existing array methods.