On Array Iteration
Published: 2022-09-10 02:35:55

Before beginning a discussion on array iteration, it is important to have a solid understanding of what an array is. An array, denoted by [] brackets, is, simply put, a collection of items. Arrays are homogenous data structures, storing elements of the same type. In an array, we can store numbers, objects, strings, Boolean values, etc. Furthermore, an array can be assigned a constant. For example, say I was making a shopping list. When I get to the store, I need to buy milk, apples, bread, and cookies. An array of these items would look like this: 

```
const shoppingList = ["milk", "apples", "bread", "cookies"]
```

Clearly, an array (in the above case, an array of strings), is a very effective method of storing information. With that said, simply storing information doesn't get us very far. We need to be able to access and manipulate the information to do work. However, simply having an array of strings does not allow us to reap the full potential of information storage. Instead, we can create an array of objects. In order to give our shopping list more details, let's turn it into such an array: 

```
const shoppingList = [
    {
      item: "milk",
      type: "dairy", 
      cost: 4.23
    },
    {
      item: "apples",
      type: "fruit", 
      cost: 2.56
    },
    {
      item: "bread",
      type: "carb", 
      cost: 1.56
    }, 
    {
      item: "cookies",
      type: "carb", 
      cost: 4.17
    }
 ]
```

By turning our array from a simply an array of strings to an array of objects, we are able to package a lot more information into the same array. With that said, having all of the information stored in an array is good, but is not very useful unless we know how to obtain and manipulate the data to our advantage. For that, let's look at some array iterators that we can use to do so. 

**.filter**

In this example, there are only four objects. But what if instead of a shopping list, this array was instead an inventory of every single product that the grocery store carries, and we wanted to find every single item that is a carb. In our example, we can just look at the array and see that there are two. However, it would be silly and ill-advised to sit and manually count through every single object in an array, then copy and paste them to a separate part of our code. Instead, we can do this using the array.filter method. 

We can start off by setting a constant of carbFoods to be all of our foods that have the type "carb." We'll do this by using the .filter and a callback function. We'll console log our constant carbFoods and see what we end up with: 

```
const carbFoods = shoppingList.filter(food => food.type === "carb")
console.log(carbFoods)

//0: {item: 'bread', type: 'carb', cost: 1.56}
//1: {item: 'cookies', type: 'carb', cost: 4.17}
```

What we get in return is all of the objects that are carbs. Let's take a bit of a closer look at what we did here.

1. We created a new constant, carbFoods, to be our new, filtered array. 
2. We took our initial array, shoppingList, and used the .filter method on it, which will create a partial copy of the array that pass the so-called test that we implement with our function. 
3. We pass in a function, with a condition of "food," that returns all of the elements, if and only if the type is "carb." 

**.forEach**

Let's say that we wanted to find out what the total cost of our grocery bill would be. Using a bit of pseudocode, we can create a logical flow of events that need to happen to get the sum. First, we need to grab the "cost" element of each object in the array. Then we need to add all of them together. For this, we could use the forEach iterator. Simply put, the forEach iterator allows us to execute a function one time for each element in an array. We could write the following code: 

```
let sum = 0
shoppingList.forEach(item => {
    sum += item.cost 
})
console.log(sum)

//12.52
```

Let's take a look at what we're doing here. 

1. First, we set our initial sum to 0. 
2. We again take our shopping list, and add a .forEach iterator to it. This iterator says that for each element in this array, I will execute the given function on it. 
3. Our function takes an argument of item, and says to sum all items with the key of "cost." In the end, we get the sum - 12.52. 

**.map**

A very useful iterator is .map. This iterator will call of every element in the array, execute a given function over every one of these elements, and in turn create a new array containing the results of the executed function. 

For example, let's say that we buy these four items every single week. Now, we want to see what our yearly budget for milk, apples, bread, and cookies is. Using the .map iterator, we can create a new array that will show us how much we would spend in a year on these items. Knowing that there are 52 weeks in a year, we can use the following code: 

```
const yearlyItems = shoppingList.map(item => item.cost * 52)
console.log(yearlyItems)

//[ 219.96, 133.12, 81.12, 216.84 ]
```
As a quick breakdown: 
1. We set a new constant, yearlyItems, to be our new array. 
2. We again took our shoppingList, and set a .map iterator to it, essentially saying that the provided function will map over every element in our array, execute the work of the function, and return a new array. 
3. We again used item as a condition of our function, took all of the values associated with "cost," and multiplied them by 52. 

**Bonus - .reduce**

This iterator simply takes every element in an array, and adds it to the previous one. In our example above, we have an array that shows us the totals that we spend in a year, individually, on milk, apples, bread, and cookies. But what if we want to know the grand total of this array of numbers? We can use .reduce: 

```
const allYearlyItems = yearlyItems.reduce((accumulator, value) => {
    return accumulator + value
})
console.log(allYearlyItems)

//651.04
```
Again, let's take a look at what we did here. 

1. We created a new constant, allYearlyItems. 
2. We took our previous constant, yearlyItems, and applied a .reduce iterator to it. *(1)*
3. We set two parameters to our function - accumulator and value. The accumulator parameter is a temporary value that contains either the initial value, or the returned value of the last call that was made. In this case, accumulator represents the initial value, which, since we did not specify, is set to 0 as a default. 
4. We asked the function to return the accumulator + value.

*(1)* It should be noted - the code above will not work unless the other part of the code where yearlyItems is defined is written in as well. Otherwise, yearlyItems.reduce will result in an error, since there is no reference for what it is.