1

I have an array like this

var array = [1,2,3,4,5,6,7,8,9,10];

Looping code is like this using _.each function in underscore.js

_.each(array,function(item,index){
  console.log(item);
});

But I want remove some items in array when looping. For example I need to remove number 5 from array and loop does not print number 5. The question is, is it possible to remove items in array when looping on this array?

2
  • 1
    I'm not familiar with underscore methods, but in a general sense it's not a good idea to remove array items when using an iterator function like .each() because (again I'm not sure about underscore, but for some other equivalents) the length of the array may be cached at the beginning so then if you remove items the iterator will run off the end. It's no problem if iterating with a traditional for loop. Commented Oct 12, 2013 at 11:11
  • @nnnnnn: It is if he forgets i-- whenever he removes the current element ;) Commented Oct 12, 2013 at 11:11

5 Answers 5

4

It's usually a very bad idea to modify an array while iterating over it. The best solution is to store the indexes in a separate array and remove them afterwards (remember to iterate over that array from last to first so you don't have to deal with changing indexes).

Sign up to request clarification or add additional context in comments.

1 Comment

Ah, I see now that when I replied to you above you'd already posted about iterating backwards. I'll delete the other comment. +1.
2

2 ways, I'd recommend the first one.

var array = [1,2,3,4,5,6,7,8],
    items_to_remove = [], i;

_.each(array, function(item,index){
    if(item === 'something'){
        items_to_remove.push(index);
    }
});

while((i = items_to_remove.pop()) != null){
    array.splice(i, 1);
}

// OR
for(i = array.length - 1; i > -1; --i) {
    if(array[i] === 'something') {
        array.splice(i, 1);
    }
}

3 Comments

Should be for (var i = array.length-1; ..., no?
first way go to infinite loop
did you change anything in it? because it doesn't here : var a = [1,2,3,4,5]; while((i = a.pop()) != null) { console.log(i); } works fine.
1

With underscore you could do this:

var array = [1,2,3,4,5,6,7,8,9,10];

var filteredList = _.filter(array, function(item){

    // do something with each item - here just log the item
    console.log(item);

    // only want even numbers
    return item % 2 == 0;

});

// show filtered list
_.each(filteredList, function(item){
    console.log(item);
});

3 Comments

@VivekJha as pointed out in the comment underneath the question it is not a good idea to modify a collection when iterating over it. This solution returns a modified collection (here only returning even numbers as an example) and showing that you could perform an operation on each item in the collection as you would when iterating (here just performing a console log).
If you filter out the elements which needs to be deleted, still you need to do a couple of steps to get them actually deleted from the main array. 1. You will have to figure out their indexes 2. Then store the indexes in a list 3. Make sure you reverse sort them 4. The use _.each to splice each index item. I would prefer the answer provided by @ThiefMaster.
Just replace the var filteredList = _.filter(...) with array = _.filter(...) and the original array is mutated.
1

You can use Undersocre to reduce the line of code. Underscore is an handy-tool.

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array = _.without(array, _.findWhere(array, {
  id: 3
}));
console.log(arr);

Comments

1

Here's a simple inline solution that worked for me using underscore's reject function:

_.each(_.reject(array, function(arrayItem) { return arrayItem === 5}), function(item){
  console.log(item);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.