Javascript - Loop through array backwards with forEach

JavascriptArrays

Javascript Problem Overview


Is there a way to loop backwards through an array using forEach (not any other kind of loop, I know how to do with with a for / standard ways) and without actually reversing the array itself?

Javascript Solutions


Solution 1 - Javascript

let arr = [1, 2, 3];

arr.slice().reverse().forEach(x => console.log(x))

will print:

3
2
1

arr will still be [1, 2, 3], the .slice() creates a shallow copy.

Solution 2 - Javascript

There is a similar array method that has a reverse counter part, reduce comes together with reduceRight:

const array = ['alpha', 'beta', 'gamma'];

array.reduceRight((_, elem) => console.log(elem), null);

When using it for the requested purpose, make sure to provide a second argument. It can be null or anything else. Also note that the callback function has as first argument the accumulator, which you don't need for this purpose.

If including a library is an option:

Lodash: forEachRight.

Solution 3 - Javascript

No, forEach only processes forward through the array. So you'd have to do something else, which you've said in your question was out of scope.

I can think of two options which just use precursors to using forEach (so, they don't use a for loop or other kind of loop). I don't know if those would be out of scope or not, so here they are:

  1. Copy the array and reverse the copy, then use forEach on it

  2. Use Object.keys to get the indexes, reverse that, then use forEach on it (which will loop through the indexes, not the values, but then we can look them up)

Here's #1:

slice copies the array (shallow copy, so not likely to be expensive), then we reverse it, then forEach:

var a = ['one', 'two', 'three'];
a.slice().reverse().forEach(function(entry) {
    console.log(entry);
});
console.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));

Here's #2:

We use Object.keys to get the array indices (using filter if you store non-element properties in your arrays), reverse that, and then loop through the result:

var a = ['one', 'two', 'three'];
Object.keys(a).reverse().forEach(function(index) {
    console.log(a[index]);
});
console.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));


Side note: Here's what I mean about using filter if you have non-element properties on your array:

var a = ['one', 'two', 'three'];
a.nonElementProperty = "foo";
Object.keys(a).filter(function(name) {
  return String(+name) === name;
}).reverse().forEach(function(index) {
    console.log(a[index]);
});
console.log("Proof that a is not, itself, reversed: " +
            JSON.stringify(a));

Solution 4 - Javascript

Just use a for loop. Start at the end of the array and go backwards from there.

const array = ['blastoff', 1, 2, 3];

for (let index = array.length - 1; index >= 0; index--) {
  const element = array[index];
  console.log(element);
}

Solution 5 - Javascript

As yet the browsers do not seem to have optimised the Array.forEach function. With not much effort you can write a simple polyfill that out performs the Array.forEach method by at least 10 to 1.

So you can create your own Array.revEach and have it outperform the native Array.forEach, thought I hope that the browsers address the very slow performance of Array.forEach soon and make the need to polyfill actual existing methods not necessary.

For Array.revEach out performs Array.forEach running 17 times faster on "Chrome 46.0.2490.22 beta-m"

if (Array.prototype.revEach === undefined) { 
    Object.defineProperty(Array.prototype, 'revEach', { 
        writable : false,
        enumerable : false,
        configurable : false,
        value : function (func) {
            var i;
            var len = this.length-1;
            for (i = len; i >= 0; i--) {
                func(this[i], i, this);
            }
        }
    });
}

Just to add the actual official polyfill modified to reverse. Comments show my changes.

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
// Modified by Blindman67 to revEach
if (!Array.prototype.revEach) {   // name changed
  Array.prototype.revEach = function(callback, thisArg) { // name changed
    var T;  // k defined where len was
    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }
    var O = Object(this);
    var k = (O.length >>> 0)-1;  // set k (counter) ToUint32
                                 // len var removed
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }
    if (arguments.length > 1) {
      T = thisArg;
    }
    while (k >= 0) {  // reverse condition
      var kValue;
      if (k in O) {
        kValue = O[k];
        callback.call(T, kValue, k, O);
      }
      k--;  // dec counter
    }
  };
}

Solution 6 - Javascript

array.forEach has 3 parameters. You can use these to effectively forEach backward.

var arr = [1, 2, 3];

    arr.forEach(function(x, index, the_array) {
        let x_prime = the_array[the_array.length-1-index]
        console.log(x_prime);
    })

will print

3
2
1

Solution 7 - Javascript

This can be accomplished relatively concisely using the reverse method, the forEach method, and (if using ES6) the arrow function

var someArray = ["a","b","c","d"];
someArray.reverse().forEach(arrayItem =>
    console.log(arrayItem)
)

If you are not using ES6, the solution is about the same, just without the arrow function.

var someArray = ["a","b","c","d"];
someArray.reverse().forEach(function(arrayItem) {
    console.log(arrayItem)
})

Both will print to the console:

d
c    
b
a

Solution 8 - Javascript

There are many ways to achive this task.

  1. Firsly we can use Array.reduceRight() method

[1,2,3,4,5].reduceRight((total,item) => {
 console.log(item);
 // Do somthing here and remember the return statement
 return item;
},0)


Output: 5,4,3,2,1

the reduceRight method traverse an array in right to left manner and we can get advantage of it.

,but always keep in mind that you have to return something to keep going this loop until the length is reached.

  1. As a second method we can use Array.reverse()

this method first format the array in reversed manner then returns it, and now you can iterate in reverse manner.

[1,2,3].reverse().map(n => console.log(n));
Output: 3,2,1

But the disadvantage of this method is that if you have thousands of entries in array then it may affect your performance.

  1. Third and the most easiest way it to use classical for loop

let array = [1,2,3,4,5];
let start = array.length;
for(;start >= 0;start--){
  // travese in right to left manner
  console.log(array[start])
}

Solution 9 - Javascript

> You can also do it this way

let arr = [1, 3, 5, 7, 9];

arr.forEach(value => {
    console.log(value);
})

let reversed = new Array(arr.reverse());
console.log("\n\nReversed: ");

reversed.forEach(value => {
    value.forEach(val => {
        console.log(val)
    })
})

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMankind1023View Question on Stackoverflow
Solution 1 - JavascriptnaartjieView Answer on Stackoverflow
Solution 2 - JavascripttrincotView Answer on Stackoverflow
Solution 3 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 4 - JavascriptAlex KView Answer on Stackoverflow
Solution 5 - JavascriptBlindman67View Answer on Stackoverflow
Solution 6 - JavascriptgrabbagView Answer on Stackoverflow
Solution 7 - JavascriptJohnView Answer on Stackoverflow
Solution 8 - JavascriptSujeet MishraView Answer on Stackoverflow
Solution 9 - JavascriptJneerView Answer on Stackoverflow