7 Ways to Iterate Over Arrays and When to Use Each
Tags: javascript, beginners, webdev, codenewbie
Published: 2021-04-17 21:52:12

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. 

```javascript
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']
```

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. 

```javascript
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."]
```



###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. 

```javascript
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.
```

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.

```javascript
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
```

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. 

```javascript
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"}
```

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. 

```javascript
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'}]
```

###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.

```javascript 
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'}
//]
```
###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. 

```javascript 
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"]
```

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.