5 ms·
Updating an array element arr[3] = 'New content'; Updating an array element immutably arr = arr.map((element, index) => { if (index === 3) return 'Ne
by mediumdeviation 9y ago
Updating an array element
arr[3] = 'New content';
Updating an array element immutably
arr = arr.map((element, index) => {
if (index === 3) return 'New content';
return element;
});
It's possible, sure, but it feels terrible. JavaScript objects want to be mutated - it's the most idiomatic way of interacting with them. Whether functional programming paradigm is good (I certainly feel it is) is beside the point - JS wasn't designed for it.
When I think of immutable primitives, I think of Python's tuples, which will raise a big fat error when you try to mutate them, or even better, Swift's structs, which gives you a new copy with every mutation.
- gr__or 9y agoif you use ES2015: arr = [ ...arr.slice(0, 2), 'New Content', ...arr.slice(3) ]
- roselan 9y agoIn my eyes this slice of code is even worse than the array map one, where there is 2.5 pieces of logic (map, if, and 2 return that makes for the .5). In the version you have 2 spread operators, an array construct and 3 hardcoded ints. I might not use the correct academic terms, and I might not be yet fully accustomed to es2015, but this way of writing stuff always make me pause and double check the code.
- mwigdahl 9y agoIn ES2017 this gets substantially better: const arr2 = Object.values({...arr, 3: 'New Content'});
- keymone 9y ago(set arr 3 "New content") (set-in deeply-nested [arbitraty path to the element] "New content") convenient updates of immutable datastructures are possible.
- hex13 9y agoI've created library `transmutable` for performing automatic copy-on-write behavior in JS (you just write imperative code which is transformed behind scenes into immutable updates https://npmjs.com/package/transmutable https://npmjs.com/package/transmutable This can avoid boilerplate traditionally associated with immutable updates in JavaScript, because you just write const copy = transform(original, stage => { stage.someArray[index] = 42; }); and it returns immutable copy of original object with appropriate mutations.
- bmpafa 9y agoI know your point wasn't strictly pertaining to boilerplate, but for an apples-to-apples comparison, the most succinct way to change a member of an array immutably would be something like: arr = arr.map((e,i) => i === 3 ? 'new content' : e) That said, idiomatic or not, functional patterns in JS are a boon for debugging (especially with Redux devtools & time travel). To your example, even if mutability is more succinct, using map() lets me chain all sorts of methods together without storing intermediate values in vars. Between the spread operator (...), immutable array methods (slice, reduce, map, filter, and even sort if preceded by .slice()), immutability in native JS ain't half bad.