Suppose you have an array like this:


const items = ["B", "M", "X"];

And now you want to replace that second item ("J" instead of "M") and suppose that you already know its position as opposed to finding its position by doing an Array.prototype.find.

Here's how you do it:


const index = 1;
const replacementItem = "J";

const newArray = Object.assign([], items, {[index]: replacementItem});

console.log(items); // ["B", "M", "X"]
console.log(newArray); //  ["B", "J", "X"]

Wasn't immediately obvious to me but writing it down will help me remember.

UPDATE

There's a much faster way and that's to use slice and it actually looks nicer too:


function replaceAt(array, index, value) {
  const ret = array.slice(0);
  ret[index] = value;
  return ret;
}
const newArray = replaceAt(items, index, "J");

See this codepen.

UPDATE (Feb 2019)

Here's a more powerful solution that uses Immer. It looks like this:


const items = ["B", "M", "X"];
const index = 1;
const replacementItem = "J";

const newArray = immer.produce(items, draft => {
  draft[index] = "J";
});

console.log(items); // ["B", "M", "X"]
console.log(newArray); //  ["B", "J", "X"]

Codepen

See this codepen.

It's more "powerful", because, if the original array (that you don't want to mutate) contains items that are mutable, you don't want to actually mutate them. This codepen demonstrates that subtlety. And this codepen demonstrates how to solve that with Immer.

Comments

Kishan B

Discovered about immer via this blog. Thanks a lot for sharing!

Your email will never ever be published.

Related posts