Zack Lee
Zack Lee

Reputation: 3044

Better(faster) way to remove elements from array?

I'm trying to remove elements from an array based on an array of indices to remove elements from the array.

Here's my code:

const array = [0, 1, 2, 3, 4, 5];
const indicesToRemove = [0, 2, 5];

for (let i = indicesToRemove.length; i--;) {
    array.splice(indicesToRemove[i], 1);
}

console.log(array);

Result: [1, 3, 4]

It seems to be working fine but I wonder if there's a better/faster way to do the same thing.

Upvotes: 4

Views: 510

Answers (3)

Chris
Chris

Reputation: 2397

Splice is the fastest method

const array = [0, 1, 2, 3, 4, 5];
const indicesToRemove = [0, 2, 5];

for (let index = indicesToRemove.length; index >= 0 ; index--) {
  array.splice(index, 1);
}

and if you work with a lot of data and make new arrays, such as filter or push, you will have memory problems.

Benchmarking:

// setup
const array1 = [...new Array(5000).keys()];
const indicesToRemove1 = [...new Array(5000).keys()];

const array2 = [...new Array(5000).keys()];
const indicesToRemove2 = [...new Array(5000).keys()];

const array3 = [...new Array(5000).keys()];
const indicesToRemove3 = [...new Array(5000).keys()];

const array4 = [...new Array(5000).keys()];
const indicesToRemove4 = new Set([...new Array(5000).keys()]);

test 1

for (let index = indicesToRemove1.length; index >= 0 ; index--) {
    array1.splice(index, 1);
}
// 3,398 ops/s ±0.71%
// fastest

test 2

for (let index = indicesToRemove2.length; index--;) {
    array2.splice(index, 1);
}
// 3,377 ops/s ±0.53%
// 0.62% slower

test 3

const newArray = array4.filter((_,i) => !indicesToRemove4.has(i))
// 3,322 ops/s ±0.5%
// 2.25% slower

test 4

const newArray = array3.filter((_,i) => !indicesToRemove3.includes(i))
// 22 ops/s ±5.6%
// 99.35% slower

Upvotes: 1

Jackson
Jackson

Reputation: 1223

How about this:

arr = array.filter( function(indicesToRemove) {
  return !toRemove.includes(indicesToRemove);
} );

console.log(arr)

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370729

If you can put the array with those elements removed into a new variable name, I'd use filter to filter out indicies which are in indiciesToRemove:

const array = [0, 1, 2, 3, 4, 5];
const indicesToRemove = [0, 2, 5];

const filtered = array.filter((_, i) => !indicesToRemove.includes(i));

console.log(filtered);

For less computational complexity, use a Set instead, that way you only have to iterate over the indiciesToRemove once, rather than on every iteration:

const array = [0, 1, 2, 3, 4, 5];
const indicesToRemove = new Set([0, 2, 5]);

const filtered = array.filter((_, i) => !indicesToRemove.has(i));

console.log(filtered);

Upvotes: 3

Related Questions