When dealing with arrays in Javascript, you frequently need to find an element inside the array and take it out or mutate it. This requires iterating over each item of the array with a for loop or an Array method like Array.find().
You may think these Array methods and for loops are interchangeable, but using the wrong method can result in slow code execution.
Array methods such as Array.forEach(), Array.map(), Array.reduce(), and Array.filter() go through the whole array. Sometimes you want that, but it can cause performance issues with large arrays.
Tip: for the best performance, don’t iterate over the whole array unless you have to.
Let’s look at the advantages and disadvantages of for loops and some array methods.
For loop
A for loop can be useful, but it has some disadvantages.
Disadvantages of a normal for loop:
- It encourages mutating the existing array
- You have to create a new variable (i)
- It’s ugly and verbose
First, let’s look at a typical for loop, then we’ll see how we can improve it. Assume we have an array of objects called products.
// in the cart we have an array of product objects
// we want to loop over the cart items, get the cart total and cart count
// we also want to grab any items over $100 to apply a discount
let cartSubTotal = 0;
let cartCount = 0;
let cartTotalWithTax = 0;
let expensiveItems = [];
for( let i = 0; i < products.length; i++ ) {
cartSubTotal = cartSubTotal + products[i].price;
cartCount = cartCount + products[i].quantity;
cartTotalWithTax = cartTotalWithTax + products[i].price + getTax( products[i].price );
// save expensive items to a new array so we can apply a special discount
if( product[i].price > 99 ) {
expensiveItems.push( product[i] );
}
}
This code will get us the cart total, item count, and the total with tax, but it’s a bit verbose. Below are 3 methods that will achieve the same thing with less code.
Use Array.reduce()* When You Want a Number
If you want to get a single number like a cart total, reduce() is the juice.
const cartCount = products.reduce( ( total, item ) => total + item.quantity, 0 );
You’ll notice the 0 as the second argument, this is the initial value for total. If we don’t add this, it will use the first array item, which is an object, and break our code.
We can do the same for the sub total and total with tax.
const cartSubTotal = products.reduce( ( total, item ) => total + ( item.price * item.quantity), 0 );
const cartTotalWithTax = cartSubTotal * 1.1; // adds 10% for tax
Use Array.filter()* to Grab a Few Items
What if we want to only grab the products that are over $100 and apply a special discount? We can use filter() for that.
// first, create a new array only with products at $100 or more
const expensiveItems = products.filter( product => product.price > 99 );
Use Array.map()* to Change Values
Next we want to discount the price by 10% on the expensive items. We can do this using Array.map().
// apply a 10% discount
const discountApplied = expensiveItems.map( product => {
let retObj = product;
retObj.price = retObj.price * .9;
return retObj;
});
Improving Performance
In some situations you can improve performance by stopping a loop when you reach the desired array item.
Use Array.find() to get an item from an array
// find an item with an id of 12
const item12 = products.find( item => item.id === 12 )
Array.find() stops iterating when it reaches the desired condition, in this case an id of 12.
If using a for loop to find a single item, break out of the loop after you’ve found it. This makes sure you don’t iterate over the whole array unnecessarily.
for( let i = 0; i < products.length; i++ ) {
if ( products[i].id === 12 ) {
// do something
break; // stop iterating
}
}
* iterates over all items, which can cause slow performance for large arrays
Comments
One response to “For loops vs Array methods in Javascript”
Map, filter, and reduce is the way! Master these 3 array methods and you level-up as a JavaScript developer