DEV Community

Cover image for How to solve index conflicts when we remove indexes in random order from an array?
Sarah Hassan
Sarah Hassan

Posted on

How to solve index conflicts when we remove indexes in random order from an array?

There are a lot of ways to remove items from an array. Today, I will discuss with you the index conflict problem that I faced while I was building my last app and how I solved it. I had an array of indexes that I should remove from the student data array.

// indexes to remove from the student data array
const selectedIndexs = [0, 3, 1];
const studentData = [
 {name:'Alice',attendanceDays:[false,true, …]},
 {name:'Lydia',attendanceDays:[false,true, …]},
 {name:'Mike',attendanceDays:[true,false, …]},
 {name:'Harry',attendanceDays:[false,true, …]},
 {name:'Julie',attendanceDays:[true,false, …]}
];

The selectedIndexs were in random order when I deleted the item in index 0 from studentData. The remaining items in studentData were shifted and this result in index conflict and removing unwanted students.
Let’s simplify the code and get to our main point, how to remove random indexes from an array? Say, I have an array of student names.

const studentNames = ['Alice', 'Lydia', 'Mike', 'Harry', 'Julie'];

Suppose I have another array containing student’s indexes we want to remove. (students at indexes 0, 2)

const selectedIndexs = [0, 4, 2] //  which refer to 'Alice', 'Julie' and 'Mike'

Alt Text

I had first thought to use iterate over selectedIndexs array using forEach and then I used the splice method to remove each studentIndex from studentNames array.

selectedIndexs.forEach( studentIndex => studentNames.splice(studentIndex, 1));

First, the student at index 0 from studentNames array will be removed and the array will be [ 'Lydia', 'Mike', 'Harry', 'Julie'].
Alt Text

Then the student at index 4 will be removed, but there isn’t a student at index 4 because indexes have been shifted and so the array will be as it is [ 'Lydia', 'Mike', 'Harry', 'Julie'].
Alt Text

Finally, the student at index 2 will be removed and the array will be [ 'Lydia', 'Mike', 'Julie'].
Alt Text

What ???

Can you guess what’s happened here?

I want to remove ['Alice', 'Julie' and 'Mike'] but instead of that 'Alice', 'Harry' were removed.
As you know the splice method manipulates the original array and does not return a new array. This is what happened in our example, the splice method changed the studentNames and that was the cause of the index conflict.
How to solve this issue? A good practice to follow when we want to remove items from an array is to start from the last index. Suppose if we want to remove array items in a random order then we need to sort indexes in descending order using the sort method.

//sort method will return [4, 2, 0]
//splice method will first remove student at index 4 then at index 2 and finally at index 0 and return ['Lydia', 'Harry']
selectedIndexs.sort((a,b) => a > b? -1 : 1).forEach( studentIndex => studentNames.splice(studentIndex, 1))

Student at index 4 first will be removed then will be removed student at index 2 and lastly the student at index 0 will be removed and studentNames will be ['Lydia', 'Harry']. This approach ensures that we remove from the last index to avoid index conflict.

Alt Text

Conclusion: 'If you want to remove items from an array in a random order you need to sort indexes in descending order first'.

Hope this helps, your feedback will be appreciated. Thanks for reading!
Resources:

MDN Docs: Array.prototype.splice()
MDN Docs: Array.prototype.sort()

Attribution: Images made by Freepik from flaticon

Top comments (0)