31

Sorry if this is a dupplicate, can't seem to find it.

var a = [1,2,3,4];
a.forEach(function(value){
  if(value == 1) a.push(5);
  console.log(value);
});

I wonder if there is a way (any sort of loop or datatype) so that this will ouput 1 2 3 4 5 during the loop (or in any order, as long as all the 5 numbers are in there)

9 Answers 9

63

Using Array.prototype.forEach() will not apply the callback to elements that are appended to, or removed from, the array during execution. From the specification:

The range of elements processed by forEach is set before the first call to callbackfn. Elements which are appended to the array after the call to forEach begins will not be visited by callbackfn.

You can, however, use a standard for loop with the conditional checking the current length of the array during each iteration:

for (var i = 0; i < a.length; i++) {
    if (a[i] == 1) a.push(5);
    console.log(a[i]);
}
Sign up to request clarification or add additional context in comments.

2 Comments

@dystroy gotta say, this may be the same code as yours, but it's a much better presented answer ;-)
true, clear explaination and this is indeed probably the best way to do it. thank you.
9

Obvious solution :

var a = [1,2,3,4];
for (var i=0; i<a.length; i++){
  var value = a[i];
  if(value == 1) a.push(5);
  console.log(value);
}

Comments

3

Since you appear to use Harmony, how about a generator like this:

function *iter(array) {
    for (var n = 0; n < array.length; n++)
        yield array[n];
}

and then

var a = [1,2,3,4];

for(var p of iter(a)) {
    if(p == 1) a.push(5)
    console.log(p)
}

prints 1 2 3 4 5

1 Comment

no not harmony. Sorry, forgot to mention. I'm using typescript which is almost like ES6 JS, and any javascript solution will do for me. changed the code example to more normal JS.
1

If you need a method that uses a callback as apposed to the for loop reduce will work.

var a = [1,2,3,4];
var result = a.reduce(function(total, item) { 
    total.push(item);
    if (item === 4) total.push(5);   
    return total;
}, []);
console.log(result);

Comments

0

Better Alternate solution:

if (a.indexOf(1) >= 0) a.push(5);
a.forEach( ... );

OK, maybe not strictly better, since it traverses the array twice. However you ought to consider why you're trying to modify the array whilst iterating over it in the first place. It's an unusual situation.

3 Comments

Note that indexOf for arrays requires a shim to work in older browsers. There's one on this page: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@MattBrowne the OP is using forEach and ES6 arrow functions - he has no need for an indexOf shim.
yes it's a bit unusual, but I specifically want to do it within the same loop because it would allow for different tactics in a simple reasoning engine I'm writing, which then may lead to better performance.
0

SO this is a quick test that seems to work well :

var a = [1,2,3,4,5];
a.forEach (function (val,index,array) { 
 if (val == 5) {  
  array.push (6);
 };  
 console.log (val); 
});

1 Comment

Does not work! ...just copy/paste in browser console and test it (I used Chrome Version 63.0)
0
a.forEach(function fn(item, index) {

if (item == 5) {  

  array.push (6);

 };

})

Comments

0
var a = [1,2,3,4];
Object.keys(a).forEach(idx => {
    if(a[idx]==1) a.push(5);
    console.log(a[idx]);
});

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

OP here. I've since learned that ES6 Sets do include items added during forEach.

So if you can use a set instead of an array, you can do:

var a = new Set([1,2,3,4]);
a.forEach(function(value){
  if(value == 1) a.add(5);
  console.log(value);
});

which does indeed log 5 as well.

Just an alternative to the for loop. Of course Sets are different than arrays in several ways, so you'd need to understand the differences and how it effects your other code.

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.