Introduction to Iterators
Imagine you had a grocery list and you wanted to know what each item on the list was. You’d have to scan through each row and check for the item. This common task is similar to what we have to do when we want to iterate over, or loop through, an array. One tool at our disposal is the for loop. However, we also have access to built-in array methods which make looping easier.
The built-in JavaScript array methods that help us iterate are called iteration methods, at times referred to as iterators. Iterators are methods called on arrays to manipulate elements and return values.
In this lesson, you will learn the syntax for these methods, their return values, how to use the documentation to understand them, and how to choose the right iterator method for a given task.
Notice the different methods being called on the arrays:
.forEach().map().filter()
Run the code to see the output!
The first iteration method that we’re going to learn is .forEach(). Aptly named, .forEach() will execute the same code for each element of an array.
The code above will log a nicely formatted list of the groceries to the console. Let’s explore the syntax of invoking .forEach().
groceries.forEach()calls theforEachmethod on thegroceriesarray..forEach()takes an argument of callback function. Remember, a callback function is a function passed as an argument into another function..forEach()loops through the array and executes the callback function for each element. During each execution, the current element is passed as an argument to the callback function.- The return value for
.forEach()will always beundefined.
Another way to pass a callback for .forEach() is to use arrow function syntax.
groceries.forEach(groceryItem => console.log(groceryItem));
We can also define a function beforehand to be used as the callback function.
function printGrocery(element){
console.log(element);
}
groceries.forEach(printGrocery);
The above example uses a function declaration but you can also use a function expression or arrow function as well.
All three code snippets do the same thing. In each array iteration method, we can use any of the three examples to supply a callback function as an argument to the iterator. It’s good to be aware of the different ways to pass in callback functions as arguments in iterators because developers have different stylistic preferences. Nonetheless, due to the strong adoption of ES6, we will be using arrow function syntax in the later exercises.
The second iterator we’re going to cover is .map(). When .map() is called on an array, it takes an argument of a callback function and returns a new array! Take a look at an example of calling .map():
const numbers = [1, 2, 3, 4, 5];
const bigNumbers = numbers.map(number => {
return number * 10;
});
.map() works in a similar manner to .forEach()— the major difference is that .map() returns a new array.
In the example above:
numbersis an array of numbers.bigNumberswill store the return value of calling.map()onnumbers.numbers.mapwill iterate through each element in thenumbersarray and pass the element into the callback function.return number * 10is the code we wish to execute upon each element in the array. This will save each value from thenumbersarray, multiplied by10, to a new array.
If we take a look at numbers and bigNumbers:
console.log(numbers); // Output: [1, 2, 3, 4, 5]
console.log(bigNumbers); // Output: [10, 20, 30, 40, 50]
Notice that the elements in numbers were not altered and bigNumbers is a new array.
Another useful iterator method is .filter(). Like .map(), .filter() returns a new array. However, .filter() returns an array of elements after filtering out certain elements from the original array. The callback function for the .filter() method should return true or false depending on the element that is passed to it. The elements that cause the callback function to return true are added to the new array. Take a look at the following example:
const words = ['chair', 'music', 'pillow', 'brick', 'pen', 'door'];
const shortWords = words.filter(word => {
return word.length < 6;
});
wordsis an array that contains string elements.const shortWords =declares a new variable that will store the returned array from invoking.filter().- The callback function is an arrow function that has a single parameter,
word. Each element in thewordsarray will be passed to this function as an argument. word.length < 6;is the condition in the callback function. Anywordfrom thewordsarray that has fewer than6characters will be added to theshortWordsarray.
Let’s also check the values of words and shortWords:
console.log(words); // Output: ['chair', 'music', 'pillow', 'brick', 'pen', 'door'];
console.log(shortWords); // Output: ['chair', 'music', 'brick', 'pen', 'door']
Observe how words was not mutated, i.e. changed, and shortWords is a new array.
We sometimes want to find the location of an element in an array. That’s where the .findIndex() method comes in! Calling .findIndex() on an array will return the index of the first element that evaluates to true in the callback function.
const jumbledNums = [123, 25, 78, 5, 9];
const lessThanTen = jumbledNums.findIndex(num => {
return num < 10;
});
jumbledNumsis an array that contains elements that are numbers.const lessThanTen =declares a new variable that stores the returned index number from invoking.findIndex().- The callback function is an arrow function that has a single parameter,
num. Each element in thejumbledNumsarray will be passed to this function as an argument. num < 10;is the condition that elements are checked against..findIndex()will return the index of the first element which evaluates totruefor that condition.
Let’s take a look at what lessThanTen evaluates to:
console.log(lessThanTen); // Output: 3
If we check what element has index of 3:
console.log(jumbledNums[3]); // Output: 5
Great, the element in index 3 is the number 5. This makes sense since 5 is the first element that is less than 10.
If there isn’t a single element in the array that satisfies the condition in the callback, then .findIndex() will return -1.
const greaterThan1000 = jumbledNums.findIndex(num => {
return num > 1000;
});
console.log(greaterThan1000); // Output: -1
Another widely used iteration method is .reduce(). The .reduce() method returns a single value after iterating through the elements of an array, thereby reducing the array. Take a look at the example below:
const numbers = [1, 2, 4, 10];
const summedNums = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue
})
console.log(summedNums) // Output: 17
Here are the values of accumulator and currentValue as we iterate through the numbers array:
| Iteration | accumulator | currentValue | return value |
|---|---|---|---|
| First | 1 | 2 | 3 |
| Second | 3 | 4 | 7 |
| Third | 7 | 10 | 17 |
.reduce() from the example above:numbersis an array that contains numbers.summedNumsis a variable that stores the returned value of invoking.reduce()onnumbers.numbers.reduce()calls the.reduce()method on thenumbersarray and takes in a callback function as argument.- The callback function has two parameters,
accumulatorandcurrentValue. The value ofaccumulatorstarts off as the value of the first element in the array and thecurrentValuestarts as the second element. To see the value ofaccumulatorandcurrentValuechange, review the chart above. - As
.reduce()iterates through the array, the return value of the callback function becomes theaccumulatorvalue for the next iteration,currentValuetakes on the value of the current element in the looping process.
.reduce() method can also take an optional second parameter to set an initial value for accumulator (remember, the first argument is the callback function!). For instance:const numbers = [1, 2, 4, 10];
const summedNums = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue
}, 100) // <- Second argument for .reduce()
console.log(summedNums); // Output: 117
Here’s an updated chart that accounts for the second argument of 100:
| Iteration # | accumulator | currentValue | return value |
|---|---|---|---|
| First | 100 | 1 | 101 |
| Second | 101 | 2 | 103 |
| Third | 103 | 4 | 107 |
| Fourth | 107 | 10 | 117 |
There are many additional built-in array methods, a complete list of which is on the MDN’s Array iteration methods page.
The documentation for each method contains several sections:
- A short definition.
- A block with the correct syntax for using the method.
- A list of parameters the method accepts or requires.
- The return value of the function.
- An extended description.
- Examples of the method’s use.
- Other additional information.
In the instructions below, there are some errors in the code. Use the documentation for a given method to determine the error or fill in a blank to make the code run correctly.
Awesome job on clearing the iterators lesson! You have learned a number of useful methods in this lesson as well as how to use the JavaScript documentation from the Mozilla Developer Network to discover and understand additional methods. Let’s review!
.forEach()is used to execute the same code on every element in an array but does not change the array and returnsundefined..map()executes the same code on every element in an array and returns a new array with the updated elements..filter()checks every element in an array to see if it meets certain criteria and returns a new array with the elements that return truthy for the criteria..findIndex()returns the index of the first element of an array that satisfies a condition in the callback function. It returns-1if none of the elements in the array satisfies the condition..reduce()iterates through an array and takes the values of the elements and returns a single value.- All iterator methods take a callback function, which can be a pre-defined function, a function expression, or an arrow function.
- You can visit the Mozilla Developer Network to learn more about iterator methods (and all other parts of JavaScript!).
Comments
Post a Comment
Thank you :)