7 Ways to Iterate Over Arrays and When to Use Each

Christine Contreras - Apr 17 '21 - - Dev Community

Accessing data within arrays and objects is an important part of Javascript that every beginner should know. There are a few common methods to iterate over arrays and objects as well as best practices of when to use each.

Iteration: the process of executing a set of statements once for each element in a collection.

A common scenario you will find yourself in while coding is needing to execute the same code over each element in an array. Instead of having to run the code for each element in a collection manually, you can iterate through the collection with built-in array methods.

The forEach() Method

The forEach method was created in ES5 to iterate over a collection of items without having to build out a for loop. It takes a callback function as its argument and executes the function once for each element in an array. One of the benefits of using forEach to iterate over arrays is that it's a non-destructive method, meaning it doesn't change the original array.

const menuItems = ['cobb salad', 'hummus dip', 'tomato soup', 'chicken sandwich', 'veggie wrap']

menuItems.forEach(item => console.log(`you ordered a ${item} today.`))
// you ordered a cobb salad today.
// you ordered a hummus dip today.
// you ordered a chicken soup today.
// you ordered a chicken sandwich today.
// you ordered a veggie wrap today.

console.log(menuItems)
//['cobb salad', 'hummus dip', 'tomato soup', 'chicken sandwich', 'veggie wrap']
Enter fullscreen mode Exit fullscreen mode

This method doesn't have a return value. If you are looking to create a new array with an output you will need to create an empty array and push the new outputs to the array. However, this isn't the most efficient way to create a new array. If you want to return a new array there are other methods in this post you can use instead.

const menuItems = ['cobb salad', 'hummus dip', 'tomato soup', 'chicken sandwich', 'veggie wrap']
const menuStatements = []

menuItems.forEach(item => menuStatements.push(`you ordered a ${item} today.`))

menuStatements
//["you ordered a cobb salad today., "you ordered a hummus dip today.", "you ordered a tomato soup today.", "you ordered a chicken sandwich today.", "you ordered a veggie wrap today."]
Enter fullscreen mode Exit fullscreen mode

When to use

The forEach method should be used sparingly. Use cases for this method are to log errors in a code, or when you want to mutate the original array or object.

The for...of & for...in Statements

These statements were created specifically to loop over arrays and objects. They are very similar to forEach with one major benefit. In a forEach method it will run the callback function over every element in a collection no matter what. With for...in and for...of you can add in control flows(continue, break, return, await).

for...in

for...in can loop over both arrays and objects but is most commonly used with objects.

const menu = {
  appetizer: 'hummus dip',
  entree: 'chicken sandwich',
  dessert: 'cake'
}

for (const key in menu) {
  console.log(`For your ${key}, we will be serving you a ${menu[key]}.`)
}
//For your appetizer, we will be serving you a hummus dip.
//For your entree, we will be serving you a chicken sandwich.
//For your dessert, we will be serving you a cake.
Enter fullscreen mode Exit fullscreen mode

Although for...in can loop through arrays, it's discouraged because it doesn't keep elements in a collection in index order. That's where the for...of loops come in handy.

for...of

The for...of statement takes into account the order of elements in a collection. This is great for arrays because it keeps the outputs in index order.

const menuItems = ['cobb salad', 'hummus dip', '', 'tomato soup', 'chicken sandwich', 'veggie wrap']

for (const item of menuItems) {
  if (item.length === 0) break
  console.log(`you ordered a ${item} today.`)
}
//you ordered a cobb salad today.
//you ordered a hummus dip today.
//breaks after empty element
Enter fullscreen mode Exit fullscreen mode

These statements still don't create a new array with the outcomes, just like forEach. Both of these methods are also not expressive, meaning they take coders longer to read through your code in order to understand your intent.

When to use

Use the for...in loop to quickly pull properties from an object and a for...of to quickly run through elements in an array without needing to create a new array with the results.

The find() Method

find() passes in a callback function as an argument. The method then loops through each element in an array and passes it through the function. The callback runs until an element meets the criteria.

const orders = [
  {appetizer: 'hummus dip', entree: 'avocado wrap', dessert: 'cake'},
  {appetizer: 'salad', entree: 'chicken sandwich', dessert: 'ice cream'},
  {appetizer: 'chips', entree: 'chicken sandwich', dessert: 'cake'}
]

orders.find(order => order.dessert === 'cake')
//{appetizer: "hummus dip", entree: "avocado wrap", dessert: "cake"}
Enter fullscreen mode Exit fullscreen mode

As you can see two objects in the array meet the criteria but only one was returned. That is because the find method returns as soon as one element meets the criteria.

When to use

Use find when you want to loop through an array using a complex callback function. This method is expressive and lets other coders understand that you are trying to loop through an array looking for only one element that meets the criteria.

The filter() Method

The filter method is similar to find but returns all elements in an array that meet the criteria. This method also returns a new array of all elements that meet the criteria.

const orders = [
  {appetizer: 'hummus dip', entree: 'avocado wrap', dessert: 'cake'},
  {appetizer: 'salad', entree: 'chicken sandwich', dessert: 'ice cream'},
  {appetizer: 'chips', entree: 'chicken sandwich', dessert: 'cake'}
]

const cake = orders.filter(order => order.dessert === 'cake')

cake
//[{appetizer: "hummus dip", entree: "avocado wrap", dessert: "cake"}, {appetizer: 'chips', entree: 'chicken sandwich', dessert: 'cake'}]
Enter fullscreen mode Exit fullscreen mode

When to use

Use filter when you want to loop through an array using a complex callback function and return all elements that meet the criteria. You can use this method to filter duplicates out of an array or find all similar objects in an array. This method is also expressive and lets other coders know to look for a new array of all the elements that meet the criteria.

The map() Method

So far the filter and find methods just pass back elements from an array. map transforms elements within an array and creates a new array for the values.

const orders = [
  {appetizer: 'hummus dip', entree: 'avocado wrap', dessert: 'cake'},
  {appetizer: 'salad', entree: 'chicken sandwich', dessert: 'ice cream'},
  {appetizer: 'chips', entree: 'chicken sandwich', dessert: 'cake'}
]

const drinks = orders.map( order => {
  return Object.assign({}, order, {
    drink: 'water'
  });
});

drinks
//[
//{appetizer: 'hummus dip', entree: 'avocado wrap', dessert: 'cake', drink: 'water'},
//{appetizer: 'salad', entree: 'chicken sandwich', dessert: 'ice cream', drink: 'water'},
//{appetizer: 'chips', entree: 'chicken sandwich', dessert: 'cake', drink: 'water'}
//]
Enter fullscreen mode Exit fullscreen mode

When to use

Use map when you want to non-destructively update objects with new key pair values, reformat objects, and change the values of the array such as multiplying all values by a number. This method is expressive and lets other coders know to look for a new array with transformed values.

The reduce() Method

The reduce method also transforms an array but reduces it into a singular value.

const orders = [
  {appetizer: 'hummus dip', entree: ['avocado wrap','chicken soup'], dessert: 'cake'},
  {appetizer: 'salad', entree: ['chicken sandwich', 'veggie wrap'], dessert: 'ice cream'},
  {appetizer: 'chips', entree: ['chicken sandwich', 'burger'], dessert: 'cake'}
]

let allEntrees = orders.reduce(
  (accumulator, currentValue) => [...accumulator, ...currentValue.entree],
[]
)

allEntrees
//["avocado wrap", "chicken soup", "chicken sandwich", "veggie wrap", "chicken sandwich", "burger"]
Enter fullscreen mode Exit fullscreen mode

In this case, we were able to combine all entrees into a singular array. The callback has two mandatory arguments. The first is the accumulator argument. This is the accumulated value for the previously returned value in the loop. Above, in the first iteration, the accumulator is an empty array.

The second iteration accumulator value is the array of the first object's entrees (['avocado wrap','chicken soup']), and so on. The second argument is the currentValue. This is the current element in the array that is being run through the callback function.

When to use

Use reduce when you want to transform an array into a singular value. This method is great to concatenate arrays, sum up values in an array, flatten arrays, and count instances of values in objects.

. . . . . .