Array Update Trick: What it is and how it works
The other day, I was looking at some code that did an immutable update of an array, replacing the value at one index with a new value. It used a slice
-based method, which took 2 spreads and several lines of code after prettier was done with it. After looking at it for a bit, I came up with a new method for doing this update. Let’s take a look at the code and walk through how it works:
The code
Assuming we have array arr
with three element, [1, 2, 3]
, and we want to update index 1
, here’s how we could do it:
The explanation
The interesting work happens on line 2, where we call Array.from
. If you’re not familiar with Array.from
, it takes an object and an optional mapper function and returns an array. It converts the object into an array and optionally calls the mapper function on each element. It can be used to convert both iterable and array-like objects into a plain JavaScript array.
The first thing we see is the spread. Note that this is an object spread, and not an array spread, so we’re spreading the array’s keys into a new object with numeric keys. An array’s keys are own properties, so doing a spread keeps them in the resulting object:
When you spread, you can update keys by placing them after the spread, so we can update the object with new keys this way.
However, if we attempted to pass this into Array.from
, it would produce an empty array, because the object is neither iterable nor array-like. According to MDN, “array-like” objects are “objects with a length
property and indexed elements.” We know the object has numeric keys, but length
is not transferred because it’s not enumerable and object spread only transfers enumerable own properties of the object. In order to make the result “array-like,” we need to give it the length
property explicitly.
The final result again:
Immutable array updates can be annoying. Hopefully this little trick will make them easier for you.