svnm
svnm

Reputation: 24378

Remove an element from an array in JavaScript with slice or spread

I have been watching the video on redux from Dan Abramov avoiding-array-mutations and I have worked out how to use slice to remove an element from an array by id, returning the new array without mutation.

var arrayOld = ['apple', 'orange', 'fig']
var index = arrayOld.indexOf('orange')
var arrayNew = arrayOld.slice(0,index).concat(arrayOld.slice(index + 1))
// ['apple', 'fig']

I was wondering how I would do the same using es6 spread syntax?

Also I am wondering why there is not a simpler way: e.g. a helper function in es6 to do this, something that works as simply as the concat method, where you could just pass in the id of the element to remove and it returns the new array, so basically splice but without the mutation.

Upvotes: 9

Views: 24104

Answers (4)

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657761

Destructuring might be what you are looking for

let [ a, ...b] = ['a', 'b', 'c'];
console.log(a); // 'a'
console.log(b); // ['b', 'c'];

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

Upvotes: 1

Oleksii Aza
Oleksii Aza

Reputation: 5398

As @thefourtheye already mentioned it is better to use .filter for your example.

However, if you want to remove an element by index using spread operator you can do the following:


let arrayOld = ['apple', 'orange', 'fig']
let index = 1;
let arrayNew = [...arrayOld.slice(0, index), ...arrayOld.slice(index + 1)];
console.log(arrayOld);
console.log(arrayNew);

Upvotes: 18

Redu
Redu

Reputation: 26191

Well i had given some thought on this subject before since in functional JS some of the array methods are not well thought. So sometims they have to be tweaked a little bit... There are two issues

  1. You shouldn't mutate what is not yours.
  2. You should return something appropriate.

So for instance when deleting an item, depending on your use case you might want to pass the deleted item or the resulted array as an argument to a function while not mutating the original array. So in this particular case you have two options such as the one like you have mentioned

myFunction(myArr.slice(0,i).concat(a.slice(i+1))) // pass resulting array as argument

or another way to have the deleted item as result.

myFunction(a.slice().splice(i,1)[0]) // pass deleted item as an argument

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239573

Why don't you filter it?

console.log(['apple', 'orange', 'fig'].filter(item => item !== 'orange'));
// [ 'apple', 'fig' ]

This returns a new array, with only the elements which satisfy the predicate function.


Note: This cannot be used as is to remove just one element, or only an element at a particular index. If that is the case, you can simply do it like this

var index = arrayOld.indexOf('orange')
console.log(arrayOld.filter((item, idx) => idx !== index));

The second parameter passed to the predicate function is the actual index of the element in the array.

Upvotes: 13

Related Questions