0

I'm trying to delete item from array based on conditional.

var Stack  = {};

Stack.items = [];

Stack.items.push({
    id: '123',
    name: 'Lorem ipsum dolor sit.'
});

Stack.items.push({
    id: '154',
    name: 'Lorem ipsum dolor sit.'
});

Stack.items.push({
    id: '123',
    name: 'Lorem ipsum dolor sit.'
});

Now, I'll delete all items with 154 id.

$.each(Stack.items, function(index, item) {
    // console.log( item.id );
    // console.log( index);
    if( item.id === '154' ) {
        Stack.items.splice(index, 1);
    }
});

But I get an undefined error in the second iteration. I think this is because splice() function modified the original array so the indexes were altered

Uncaught TypeError: Cannot read property 'id' of undefined

I'm getting the expected results with lodash but i'm trying to not use them just for this issue

_.remove(Stack.items, function(item) {
    return item.id === '123';
});

Thanks!!

mauriblint
  • 1,802
  • 2
  • 29
  • 46
  • 1
    It's usually not a great idea to change a collection *while you are iterating it* for exactly this reason. You could either make one pass to find the indexes to remove and then iterate that collection to remove items. Or you can start at the end of the array and work towards the first element so that the items that you have yet to process aren't moving. Or you can copy the items that don't have `id === '123'` to a new collection (with `filter` for example). – Matt Burland Dec 03 '15 at 19:55

1 Answers1

4

If you must need in place modifications, you will want to use another approach. Your indexes must only be incremented if the element was not removed. An example would be:

var index = 0;
while ( index < Stack.items.length ) {
    var item = Stack.items[index];
    if ( item.id === '154' )
        Stack.items.splice(index, 1);
    else
        index++;
}

However, creating a copy of the array and using that would make the code much easier to follow, and is a lot quicker to code:

var newItems = Stack.items.filter(function(item) {
    return item.id !== '154';
});
TbWill4321
  • 8,626
  • 3
  • 27
  • 25
  • [$.grep](http://api.jquery.com/jquery.grep/) provides similar functionality if you need to support IE 8. – csum Dec 03 '15 at 20:03