Array Prototype Iteration Methods

Prework

Before we dive into array prototype iteration methods, we’d like you to review for loops. A lot of these methods work very similar in that they iterate through an array. Understanding how a for loop works and is used will help you in your understanding of this lesson.

If we look at the MDN documentation, we can see the syntax of a for loop:

for ([initialization]; [condition]; [final-expression]) {
  statement
}

The initialization starts with a counter variable. Typically, this counter starts at zero, but you can specify any number. The condition is an expression evaluated each time the loop finishes executing an iteration. If the condition is true, the loop continues iterating. The final-expression statement is executed at the end of each loop iteration, which is usually used to increment the initialization counter. Usually the increment is by one, or i++ for shorthand.

For example, we can log the counter variable to the console for each iteration, which is the first example on the MDN docs.

for (var i = 0; i < 4; i++) {
   console.log(i);
}

The output to the console will look something like:

0
1
2
3

Let’s follow what happens to i in the for loop. Each of the rows in the table can be referred to as an iteration, a term we will hear a lot when dealing with arrays and loops.

i Condition What happens for each iteration?
0 (0 < 4) true 0 is logged to the console; i increases by 1
1 (1 < 4) true 1 is logged to the console; i increases by 1
2 (2 < 4) true 2 is logged to the console; i increases by 1
3 (3 < 4) true 3 is logged to the console; i increases by 1
4 (4 < 4) false statements in the loop are not executed

The previous example didn’t deal with an array, so let’s use an array with a for loop. We can use for loops to iterate through an array.

var letters = ['a', 'b', 'c'];

for (var i = 0; i < letters.length; i++) {
  console.log(letters[i]);
}

In the example above, we set up an iterator, i. As long as i is less than the length of the array of letters, we’ll keep calling the body of the loop. After we call the body of the loop, we’ll increment i, which will eventually become greater than the length of the array and the loop will exit. The letters.length part of the loop condition gives us the ability to change the size of the letters array without having to change the condition.

If we put the above example in our console, then we should see this output:

a
b
c

Notice that the condition is crucial in controlling the flow of our loop. If the condition is never false, then the loop will become an infinite loop and never stop running until we stop it or our computer runs out of memory. This is one delicate part of for loops to watch out for.

Learning Goals

  • Understand and know when to implement the following array prototype methods:
    • forEach()
    • map()
    • filter()

Vocab

  • callback function A function that is passed to another function to be ran at a later time
  • array A data structure consisting of a collection of elements (values or variables), each element is identified by an index
  • index The position of each element within an array
  • iteration A set of instructions that are repeated a specificed number of times or until a condition is met
  • truthy A value that is considered true when evaluated in a Boolean context
  • falsy A value that is considered false when evaluated in a Boolean context

Context

We went over some of the different array prototype methods we have available to us. Today we want to focus on methods that are more focused on iterating through arrays. There are many times we want to manipulate arrays, add all of their values, retrieve items based on some condition…

We could do these things by hand using a for loop, but we would have to implement our own logic to work with the array. So instead, let’s use the methods that the Javascript language provides us.

Your Turn

Let’s see what it’s like to use a for loop to solve these problems first. We’ll then see how we can use array prototype methods to solve them and the benefits they provide!

  • Use the prices array below to create a new array of increased prices.
// increase prices by 1.00
var prices = [4.99, 5.50, 7.00, 10.25];
var increasedPrices = [];

// use a for loop to loop over the array and add new increased prices to the increasedPrices array
  • Using the array below, log the dog’s name and how many legs it has.
var dogs = [ 
  {name: "Fido", numLegs: 4}, 
  {name: "Greg", numLegs: 5} 
];

Array.prototype.forEach

Let’s get into array prototype methods. One of the first methods we’ll explore together is Array.prototype.forEach(), which iterates over the array and passes each element into a callback function that you provide.

var letters = ['a', 'b', 'c'];

letters.forEach(function (letter) {
  console.log(letter);
});

This will log the following output to the console, just like our for loop example in the prework:

a
b
c

forEach() passes three arguments to the callback function: the current element for this iteration, the index of that element, and a full copy of the array that we’re iterating through.

var letters = ['a', 'b', 'c'];

letters.forEach(function (letter, index, array) {
  console.log({
    currentValue: letter,
    currentIndex: index,
    fullArray: array
  });
});

This will log the following output to the console:

{currentValue: "a", currentIndex: 0, fullArray: ["a", "b", "c"]}
{currentValue: "b", currentIndex: 1, fullArray: ["a", "b", "c"]}
{currentValue: "c", currentIndex: 2, fullArray: ["a", "b", "c"]}

The index and array parameters are optional and do not need to be included if you are not using them.

Advantages of forEach()

  • Easier to write/read
  • The first parameter, letter is block scoped whereas i in a for loop is globally scoped
  • Is the foundation for many other array prototype methods (specifically ones we are covering today)

One Note:

One thing to note is that forEach does not return anything back to you. Having a return statement in the callback function will not give you anything back. This is a major difference compared to the other array prototype methods we will go through today.

Your Turn

These look familiar…let’s compare the structure to what we had before using the for loop now with forEach.

  • Use the prices array below to create a new array of increased prices.
// increase prices by 1.00
var prices = [4.99, 5.50, 7.00, 10.25];
var increasedPrices = [];

// use forEach to loop over the array and add new increased prices to the increasedPrices array
  • Using dogs array below, log the dog’s name and how many legs it has.
var dogs = [ 
  {name: "Fido", numLegs: 4}, 
  {name: "Greg", numLegs: 5} 
];

And one additional:

  • If we have two arrays, add the pairwise items in those arrays and log them to the console; var array1 = [1, 2, 3] and var array2 = [4, 5, 6]. So we should end up with 5, 7, 9.

Journal

Open your journal and answer the following questions:

  • What are the most important/significant ideas or elements of the forEach() method?
  • When might you use a forEach method in the project you are currently work on?

Array.prototype.map

It’s not uncommon that we find ourselves in a position where we need to transform the contents of an array.

In theory, we could use forEach() like this:

var letters = ['a', 'b', 'c'];
var uppercaseLetters = [];

letters.forEach(function (letter) {
  var uppercaseLetter = letter.toUpperCase();
  uppercaseLetters.push(uppercaseLetter);
});

console.log(uppercaseLetters);

The console.log statement will log ['A', 'B', 'C'] — we’ve mapped each element in the array to its uppercase equivalent. However, JavaScript’s Array provides us with a better way to do this — Array.prototype.map().

How is map() similar to forEach()?

  • map() takes a callback function and runs through each element in the array
  • It also has the same parameters as a forEach() method including the index and array as optional parameters

How are they different?

  • forEach() returns undefined. map() returns a new array based on the values returned by the callback function.
  • map() is most commonly used to manipulate the data from an array into a new one
var letters = ['a', 'b', 'c'];

var uppercaseLetters = letters.map(function (letter) {
  return letter.toUpperCase();
});

console.log(uppercaseLetters);

Although this produces the same result, the code is significantly cleaner and doesn’t mutate the original data.

Your Turn

  • Use the prices array below to create a new array of increased prices.
// increase prices by 1.00
var prices = [4.99, 5.50, 7.00, 10.25];
var increasedPrices = [];

// use map to loop over the array and add new increased prices to the increasedPrices array
  • From before, if we have two arrays, add the pairwise items in those arrays and log them to the console; array1 = [1, 2, 3] and array2 = [4, 5, 6]. This time we should end up with an array [5, 7, 9].

  • Using an array of temperature data in Fahrenheit, convert the date to degrees Celsius; degreesF = [67, 32, 55, 102]. It should roughly become [19.44, 0, 12.77, 38.88]. Here is the formula to convert from Fahrenheit to Celsius.

Journal

  • What parts of map() are similar to forEach()? What parts are different?
  • What is a situation where you might use map()? List 2-3 examples.

Array.prototype.filter

Something to note is that map() always returns an array of the same length. What if I wanted to shorten my array based on some conditional? That’s where Array.prototype.filter() comes in!

How is filter() similar to map()?

  • Returns a new array based on the value returned from the callback function
  • It also has the same parameters as forEach() and map() including the index and array as optional parameters

How are they different?

  • The value returned from the callback function must be truthy or falsy. (more on this shortly)
  • filter() is used for taking values out of an array based on a conditional. You cannot manipulate the data like you can with map().

Truthy vs. Fasley

filter() will only add an element to the new array if the callback function returns a truthy value. If the callback function returns a falsy value it will be omitted.

What makes a value truthy or falsy? Let’s start with the easy ones: true is truthy and false is falsy. 0, null, undefined, NaN, and an empty string are all falsy as well. Everything else is truthy.

Let’s start with a simple example:

var booleans = [true, true, false, true];

var truths = booleans.filter(function (value) {
  return value;
});

console.log(truths); // Logs [true, true, true]

The false values are omitted from the resulting array. Let’s look at a more practical example:

var numbers = [15, 6, 14, 2, 9, 22];

var numbersLargerThanTen = numbers.filter(function (number) {
  return number > 10;
});

console.log(numbersLargerThanTen);

All the numbers greater than 10 will be added to our new array, numbersLargerThanTen.

Here’s another example that focuses on truthy/falsy values:

var numbers = [1, 2, 3, 4, 5, 6, 7];

var oddNumbers = numbers.filter(function (number) {
  return number % 2;
});

console.log(oddNumbers); // Logs [1, 3, 5, 7]

All of the even numbers are omitted from the new array because number % 2 returns the falsy value 0. For all of the odd numbers, number % 2 returns 1, which is truthy. As a result, a new array of odd numbers are returned.

He’s one final example where we can use filter on an array of objects:

var beatles = [
  { name: 'John', living: false, instruments: ['guitar', 'bass', 'piano'] },
  { name: 'Paul', living: true, instruments: ['bass', 'guitar', 'piano'] },
  { name: 'George', living: false, instruments: ['guitar', 'sitar'] },
  { name: 'Ringo', living: true, instruments: ['drums', 'bongos'] },
];

var livingBeatles = beatles.filter(function (beatle) {
  return beatle.living;
});

var guitarPlayingBeatles = beatles.filter(function (beatle) {
  return beatle.instruments.indexOf('guitar') !== -1;
});

Your Turn

  • From the array [34, 2, 55, 75, -1, 100], return an array with only numbers greater than 50.

  • Filter the array to return objects that are not thirsty:

var people = [
  {name: "Martha", thirsty: true}, 
  {name: "Pam", thirsty: false}, 
  {name: "Roberta", thirsty: true}
];

Journal

  • How is filter() similar to map()? How are they different?
  • How could you put filter() into practice on one of your current projects?

Summary

forEach()

  • How is forEach() better than a for loop?
  • In what scenario would I use forEach()?
  • Does forEach return anything to me? Can I store it in a variable?

map()

  • In what scenario would I use map?
  • Does map return anything to me? Can I store it in a variable?
  • Using map, can I return an array of a different length from the original?

filter()

  • In what scenario would I use filter?
  • Does filter return anything to me? Can I store it in a variable?
  • Using filter, can I return an array of a different length from the original?

Additional Resources

Lesson Search Results

Showing top 10 results