DEV Community

Madhavan Nagarajan
Madhavan Nagarajan

Posted on

Stop using for loops, here are other cool options

If you are someone who always resorts to the for loop and forEach loop to iterate over items in an array, then this is for you. We will explore a few array methods that you can employ as an alternative to a simple “for” loops.

There are a lot of advantages of using specific methods over generic for or forEach version.

  • It’s easy to write and others can interpret it easily
  • It’s easy to maintain, extend, and test
  • You can write pure functions without any side effects
  • Helps you thinking in terms of functional programming
  • If you ever plan to use libraries like RxJS, it will surely help

Using Map

The below code looks pretty familiar, right? You see that the for loop is taking each element from the array, performing some operation (here it is multiplying numbers), and putting that into a new array.

find square of numbers
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//for Version
var squareNumbers = [];
for (var counter=0; counter < numberArray.length; counter++){
   squareNumbers.push(numberArray[counter] * numberArray[counter])
}
console.log(squareNumbers);

Array.map is a builtin function that yields a new array by transforming each element of the source array to a new value based on the supplied method for transformation.

It loops over all the elements in order, calling a supplied transformation function for each element, and internally pushes the results into a new array. We just need to supply the transformation function, and the rest of the work will be done by the map function. For example:

find the square of numbers
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//Map version
var squareNumbers = numberArray.map(number => number*number);
console.log(squareNumbers);

In simple terms, Array.map() transforms a given array into a new one after performing the transformation function on each element in the array.


Using Filter

You see that the below for loop is taking each element from the array, checking some condition (here it is checking number is even or not), and if the condition is true then it puts that into a new array.

Filter even numbers
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//for Version
var evenNumbers = [];
for (var counter=0; counter < numberArray.length; counter++){
    if (numberArray[counter] %2 === 0){
        evenNumbers.push(numberArray[counter])
    }}
console.log(evenNumbers);

Array.filter is another handy function that builds a new array of elements based on the given “validator” functions. It loops over all the elements of the source array, calling the “validator” function for each item, if the “validator” function returns true, the element will be internally added to a new array. With the filter function, we can just supply the core “validation” logic of the function, leaving the rest of the work to the filter which makes it easy to write and understand.

Filter even numbers
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//filter version
var evenNumbers2 = numberArray.filter(number => number%2===0);
console.log(evenNumbers2);

Looking at the same function implemented with filter(), it becomes clear immediately that it's filtering the original array based on the condition used inside the “validator” function.

With the for and forEach version, we need to analyze that there is an empty array and then elements are added to it based on the condition. With the filter function, we only need to think of the validation function logic and leaving the rest to the filter, and that makes the code looks sleek and natural.


Using reduce

Another familiar for loop is where we take each element and do some kind of accumulation operation (here it is adding all the elements), returning the accumulated value.

find sum of elements in the array
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//for version
var sum = 0;
for (var counter=0; counter < numberArray.length; counter++){
     sum += numberArray[counter]
}
console.log(sum);

Array.reduce() is used when you want to process all the elements of an array to get a single value out of it. Reduce is a little tricky one to understand in beginning but once you understand it’s really simple to use.

It is important to note that Array.reduce() doesn't execute the function when there is no item in the array and also this method doesn’t make any change to the original array.

Array.reduce takes two arguments, one is the reduce function and second is the initial value which is called an accumulator. It calls the reduce function for each element by giving the accumulator value. The reduce function processes the current element and updates the accumulator value and passes it to the next iteration. At the end of the last loop, accumulator becomes the final result.

Let's explore with example

find sum of all elements in the array
var numberArray = [1,2,3,4,5,6,7,8,9,10];
//Reduce version
var sum = numberArray.reduce(((acc, num) => acc + num), 0);
console.log(sum);

Function composition

There are other array utility methods like every, slice, splice, some, concat, sort which everyone should be aware of. Using the right kind of function not only makes the code cleaner, but it also makes it easy to test and extend. Plus you are writing futuristic code by using these functions. These functions are native JavaScript functions that are supported in all the browsers and are getting faster day by day. It also helps to compose smaller functions to create a broader use case.

using evenNumbers and sum, we can easily fund sum of even numbers
var numberArray = [1,2,3,4,5,6,7,8,9,10];
var FilterFn = (number => number%2===0);
var squareMapFn = (number => number*number);
var sumFn = ((sum, number) => sum + number);
var sumOfSquareOfEvenNums = numberArray
                               .filter(FilterFn)
                               .map(squareMapFn)
                               .reduce(sumFn,0);
console.log(sumOfSquareOfEvenNumbers)

Writing the above example with a conventional for loop will take more lines of code, that ultimately makes it less clear.


Note on performance

Array.filter, map, some have the same performance as forEach. These are all marginally slower than for/while loop. Unless you are working on performance-critical functionalities, it should be fine using the above methods. With JIT, JavaScript execution engines are very fast and it's getting even faster day by day. So start taking advantage of these methods in your application.


Thank you for reading my article. ✌🏻👨🏼‍✈️

Top comments (8)

Collapse
 
itismadhavan profile image
Madhavan Nagarajan

I can understand the point you are making here. I was very sceptical like you that these functions cannot work in real-time coding practice but it turns out that I'm wrong I've used these functions and replaced many of the for loops in the older code bases and that worked alot for my team. I also agree there are cases where you cannot use these methods but when you want to break a loop conditionally i would use a while over for and that's my idea . I would encourage you to try out this in your workplace if you need any help I'm happy to help :)

Collapse
 
aminnairi profile image
Amin • Edited

Thanks for your article! I too really like those cool little Array.prototype methods.

May I suggest another name for the FilterFn function, which is upper-camel-cased. Usually we write functions following the lower-camel-case conventions.

Of course this is non-blocking when writing code but if you are going on the readability path, you may want to convert this code and use this convention for your function names!

Another thing I noticed is the name of the function itself. I guess isModuloTwo is more self-explanatory than FilterFn since you may want to re-use this function elsewhere in your code.

Finally, suffixing all your functions with Fn is overkill. If you follow the above convention and some others, you'll easily identify functions, classes, constants, etc...

"use strict";

const isModuloTwo = number => number % 2 === 0;

const evens = [1, 2, 3, 4, 5].filter(isModuloTwo);

console.log(evens); // [2, 4]
Collapse
 
itismadhavan profile image
Madhavan Nagarajan

I totally agree your point. It is very important to name the functions right to express the intention of the function. In fact that is my next piece of topic I'm writing. watch out for that :)

Collapse
 
yokotobe profile image
yokotobe

Instead of say "Stop using for loop, let's say "Alternative choice to iterate"

Collapse
 
itismadhavan profile image
Madhavan Nagarajan

May be 🤔 , But if there is no special reason to use "for" or "foreach" i would still say stop using them. Using some of the array functions will definitely improve readability of code than a conventional for version

Collapse
 
yokotobe profile image
yokotobe

That is true. One more thing to be considered is performance. Do some benchmark of each method?

Thread Thread
 
itismadhavan profile image
Madhavan Nagarajan

Conventional for loop is always performant that any of the alernatives mentioned here. But I've not seen any bigger difference may be in milli seconds(ofcourse not with millions of data that case for might outperform). But in most of the day to day stuff its better to use any of the functions metioned above over the traditional couterpart

Thread Thread
 
yokotobe profile image
yokotobe

Nowaday, hardware is cheap. You can have power of CPU to solve software performance issue.