2

I am trying to iterate an array with forEach and, based on a condition, I do something.

For this question, I simplified the condition in order to try to understand what's going on.

I expect array b = [] after the operation, but it is not, as it operates only on half on the elements. Why does this happen?

(This is not about removing everything from b, just trying to understand why it jumps the even indexes).

var a = [1, 2, 3, 4, 5, 6];
var b = a.slice(0);

console.log('before b = ', b); // b = [1, 2, 3, 4, 5, 6]

a.forEach(function (e) {
    if (e > 0) {
        b.splice(a.indexOf(e), 1);
    }
});


console.log('after b = ', b); // b = [2, 4, 6]

// but I expect b = []

3 Answers 3

3

It does not. It goes through each and every item. The thing is what you do with array b. First you remove the index 0 from it which is 1. So now b = [2,3,4,5,6]. Then index 1 which is 3 so b = [2,4,5,6]. Then index 2 which is 5 so b = [2,4,6]. The next indexes don't exist so in the end b = [2,4,6].

To have the expected outcome use b.indexOf(e) in your splice call.

var a = [1, 2, 3, 4, 5, 6];
var b = a.slice(0);

console.log('before b = ', b); // b = [1, 2, 3, 4, 5, 6]

a.forEach(function (e) {
    if (e > 0) {
        b.splice(b.indexOf(e), 1);
    }
});


console.log('after b = ', b); // b = [2, 4, 6]

// but I expect b = []

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

3 Comments

Thanks. I understand now.
I feel so dumb now. The thing is that, initially, there was only a array and I was slicing it directly, but still getting only half of the expected results. Later I added b in order to understand what was happening. I think there was another problem inside the function which made it skip elements.
You are welcome, you have to be careful when you splice an array within the forEach
2

You could take the index directly for splicing and make an log from the value an the array. You se, that the array becomes smaller than the index for splicing.

var a = [1, 2, 3, 4, 5, 6];
var b = a.slice(0);

console.log(b.join(' '));

a.forEach(function (e, i) {
    if (e > 0) {
        b.splice(a.indexOf(e), 1);
        console.log(i, ': ', b.join(' '));
    }
});

console.log(b); // b = [2, 4, 6]

To empty b, you need to look for the index of the array b, not a and splice it.

var a = [1, 2, 3, 4, 5, 6];
var b = a.slice(0);

a.forEach(function (e, i) {
    if (e > 0) {
        b.splice(b.indexOf(e), 1);
        //       ^
    }
});

console.log(b);

Comments

1

You're splicing based on the index of the element from a, however b's indices are getting updated when you splice in it. You should try to splice from b based on the index of the element IN b.

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.