Most of the time when you’re looping over an array of elements, you’ll do it sequentially. However, I recently needed to iterate through an array of objects in reverse just using a plain old for loop.
This will not be a highly informative or groundbreaking post but, I thought I’d share this in case someone wants to solve the same problem and might be confused with the many different ways you can loop over an array in reverse.
I had an idea in mind, I knew Array.reverse
would be the ideal candidate but I still Googled to see if smarter developers than me figured something better out.
Turns out, there are a lot of scary alternatives to looping an array in reverse (mostly on StackOverflow). Some people are proponents of decrementing and using while loops, others had different ideas. Why not just use a function that’s existed since the dawn of Javascript?
var myItems = [
{name: 'Dwayne'},
{name: 'Rob'},
{name: 'Marie'},
{name: 'Sarah'},
{name: 'Emma'},
{name: 'James'}
];
var itemsToIterate = myItems.slice(0).reverse();
for (var i = 0, len = itemsToIterate.length; i < len; i++) {
var item = itemsToIterate[i];
}
In our example, we take an array of items and then we use slice
to make a copy of our array starting at its first index (zero). Then we call reverse
on the cloned array.
I said efficient in the title, but I haven’t benchmarked anything. However, we are using a barebones for loop and you don’t really get much faster than that. Sometimes commonsense and readability beat microoptimisating.
The reason we copy the array is so we don’t modify the original array. Using slice allows us to effectively clone the array and gives us a new instance, there are other ways of doing the same thing but I find this way is the cleanest.
Without slice, you’ll be modifying the provided value to our function and might produce an unintended result doing so. I tend to keep my functions pure for this kind of thing, nothing that gets input should be modified.
Thanks to reverse flipping our array upside down, we iterate like we would normally. Breaking out the reverse functionality into a function might also be a great idea. This would allow us to easily test our functionality from within a unit test.
function reverseArray(array) {
return array.slice(0).reverse();
}
One thing to keep in mind is for my use-case, slice
worked — if you’re dealing with arrays containing object references or nested arrays or complex objects, slice
does not do a deep copy.
Lodash has some great methods for doing recursive and deep cloning of arrays and collections if you need that kind of power. Post your thoughts and suggestions in the comments below.