Loop through array in reverse to remove multiple elements

Sunday, May 10, 2020
JavaScript

Let's say we have multiple items to remove from an array. If we try to remove these elements by traversing from start to end, only the first item will be removed correctly. After we remove the first item, all the elements to the right are shifted by one index to the left, resulting in removal of wrong elements based on the original indices. In the example below, a has 10 elements and we desire to remove elements at indices 2, 4 and 6. Since values are same as indices in this array, we would expect to remove 2, 4 and 6 from the array but only 2 is removed correctly.

let a = [];

for (let i = 0; i < 10; i++) {
    a.push(i);
}
console.log("Original a:");
console.log(a);
// removing elements at indices 2, 4 and 6
// looping from begining to end
let killIndices = [2, 4, 6];
for (let i = 0; i < a.length; i++) {
    if (killIndices.indexOf(i) != -1) {
        a.splice(i, 1);
    }
}
console.log("Modified a:");
console.log(a);
Original a:
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Modified a:
[ 0, 1, 3, 4, 6, 7, 9 ]

Solution

Start the loop from end and go to beginning. This avoids traversing the indices that gets shifted.

let b = [];

for (let i = 0; i < 10; i++) {
    b.push(i);
}
console.log("Original b:");
console.log(b);
// removing elements at indices 2, 4 and 6
// looping from end to beginning
for (let i = b.length - 1; i >= 0; i--) {
    if (killIndices.indexOf(i) != -1) {
        b.splice(i, 1);
    }
}
console.log("Modified b:");
console.log(b);
Original b:
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Modified b:
[ 0, 1, 3, 5, 7, 8, 9 ]