37

I need to remove an element from an array that is a state of a React Component. Which means that it is an immutable object.

Adding a element is easy using spread syntax.

    return {
        ...state,
        locations: [...state.locations, {}]
    };

Removing is a little more tricky. I need to use an intermediate object.

        var l = [...state.locations]
        l.splice(index, 1)
        return {
            ...state,
            locations: l
        }

It make the code more dirt and difficult to understand.

Is there an easier or less tricky to create a new array removing an element from it?

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Daniel Santos
  • 14,328
  • 21
  • 91
  • 174
  • 1
    `const arr = ['a', 'b', 'c', 'd', 'e']; delete arr[2]; console.log(arr.filter(Array))` – dandavis Oct 30 '17 at 21:44
  • 2
    @zerkms I feel like this question is better than the duplicate since this is irrelevant of the library used while the dupe target's answers are polluted by Redux syntax. – Emile Bergeron May 03 '19 at 15:54
  • @EmileBergeron the marked answer there has 0 connection to redux and is a generic JS. The first example in the second answer is generic JS. To me - it looks ideal for the person who is willing to learn, not copy-paste. – zerkms May 03 '19 at 20:34

1 Answers1

88

You can use a combination of spread and Array#slice:

const arr = ['a', 'b', 'c', 'd', 'e'];

const indexToRemove = 2; // the 'c'

const result = [...arr.slice(0, indexToRemove), ...arr.slice(indexToRemove + 1)];

console.log(result);

Another option is Array#filter:

const arr = ['a', 'b', 'c', 'd', 'e'];

const indexToRemove = 2; // the 'c'

const result = arr.filter((_, i) => i !== indexToRemove);

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • One thing worth noting is that using `filter` without the index will remove all matching values if that is not your intention. You also have to search the entire array if you already have the index readily available; using `filter` on a large collection could be intensive. I just wish JS had a cleaner way than double slicing to remove an item without touching the original array. – CTS_AE Jan 22 '22 at 00:46
  • 1
    My friend and I had a debate about this over the weekend shortly after I posted my comment. We benchmarked a few different ways of removing an item from an array (slicing, filter, for loop), surprisingly filter came out the fastest, although I'm not sure I am completely sold on it, I think it depends how you build the array back out (spreading, push, concat). I was reminded that creating a copy of an array still requires us to walk the original array, thus this is why filter is viable. Still it's baffling this is not part of the standard JS library. – CTS_AE Jan 24 '22 at 22:25