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)
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
overfor
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 :)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 thanFilterFn
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...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 :)
Instead of say "Stop using for loop, let's say "Alternative choice to iterate"
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
That is true. One more thing to be considered is performance. Do some benchmark of each method?
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 casefor
might outperform). But in most of the day to day stuff its better to use any of the functions metioned above over the traditional couterpartNowaday, hardware is cheap. You can have power of CPU to solve software performance issue.