Array Iterations - What makes them so useful?
Julie Cheng
Posted on June 13, 2023
Learning about the built-in array iterator methods was a game changer for me. It quickly became one of my favorite Javascript tools in manipulating arrays. I was able to make my code cleaner with less lines needed.
How should you use them? When do you use them? What makes one method better to use than another? Why do I consider it an important tool to know in JavaScript?
What is an Array?
Let's start from the beginning.
As defined in the MDN website: An array is an ordered collection of data. In other words, it is a list that holds multiple individual data together. Instead of using multiple variables to call the entire collection, we could just use one name for the entire array.
const first = 1
const second = 2
const third = 3
//use this instead
const myArray = [1, 2, 3, 4, 5]
What's next?
Now that we have an understanding of what an array is, let's talk about array iterations.
So, what if I need to manipulate each of the elements in myArray in a specific way? We could use a for..of loop to do it.
const myArray = [1, 2, 3, 4, 5]
const newArray = [ ]
for (const num of myArray) {
newArray.push(num*2)
}
//=> newArray = [2, 4, 6, 8, 10]
It looks good. We were able to multiply each element by 2 and push each result in a new array. But we will need to declare an empty array each and every time. There is another way where you don't need the extra declaration - by using map.
const myArray = [1, 2, 3, 4, 5]
const newArray = myArray.map(num => num *2)
//=> newArray = [2, 4, 6, 8, 10]
Using map had allowed me to use fewer lines of code to produce the same result. Another advantage of using map is that its expressive. In other words, when another programmer reads the code they will know that map will modify each element of the array and will return a new array with the modified elements. In comparison, with using for...of, the programmer will need to read the entire block code to understand what the code is doing and what will be returned.
Another iteration method that is commonly used is filter, in which it will return a new array with all the elements that meet a condition (i.e. returns true) set by the callback function.
const myArray = [1, 2, 3, 4, 5]
const oddArray = myArray.filter(num => (num % 2) === 1)
//=>oddArray = [1, 3, 5]
Like map, using filter is expressive. It implies that it will filter out the array elements that do not pass the condition and return a new array containing all the elements which do.
So far, both map and filter methods are returning an array. However, the reduce method returns a single summary result. Reduce will execute the call back function for each element of the array, while passing the return calculated value from the previous element until the final aggregate result is left. Note: When using reduce, the callback function is passing two parameters; accumulator and the current number element. Accumulator should always be the first argument and the second argument will be the array element. The order matters.
const myArray = [1, 2, 3, 4, 5]
const myResult = myArray.reduce(function(accumulator, num){
return num + accumulator
}, 0)
//=> myResult = 15
Note that reduce take an optional initial accumulator value parameter. For this example, the initial value is 0. If no initial value is provided, the first element of the array is used as the starting value and second element will be pass through the callback function with the first element as the accumulator. Meaning the first element is skipped and will not be executed by the callback function. With addition this is not be an issue, but what if the callback function something more complex.
const myArray = [2, 3, 4]
const doubleResult = myArray.reduce(function(accumulator, num){
return num * 2 + accumulator
}, 0)
//=> doubleResult = 18
//Without an initial value
const myArray = [2, 3, 4]
const doubleResult = myArray.reduce(function(accumulator, num){
return num * 2 + accumulator
})
//=> doubleResult = 16
Look at that. Two different results. As a good practice when using reduce, remember to include an initial value to avoid getting an unexpected result.
forEach is another array iterator method. It is known as the least expressive and has no return value. You could think of forEach as the most generic of all iterator methods. It will execute the callback function once for each array element. forEach can be used in replacement of reduce or map and produce the same results, however it will lose the expressive that using reduce or map provide. That is the intention of the function becomes unclear for another programmer.
const myArray = [2, 3, 4]
function doubleResult(numArray) {
let total = 0
numArray.forEach(function(num){
total = num * 2 + total
})
return total
}
//=> doubleResult(myArray) = 18
So when should you use the forEach method? Since forEach does not return anything, the best time to use it is when you don't need anything to be return back. For example, during a debugging process, forEach can be used to log each array element.
unknownArray.forEach(function(e){
console.log("I am" + e)
})
Another time forEach will be appropriate is when the array elements need to be mutated or changed. The previous mentioned iteration methods (map, filter, reduce) are nondestructive, meaning they do not change the original array.
const myArray = [
{name: "Spot", pet: "dog"},
{name: "Mittens", pet: "cat"},
{name: "Bow", pet: "bird"}
]
myArray.forEach(function(e){
e.isCute = "yes"
})
/*=> myArray = [
{name: "Spot", pet: "dog", isCute: "yes"},
{name: "Mittens", pet: "cat", isCute: "yes"},
{name: "Bow", pet: "bird", isCute: "yes"}
] */
There are other array iteration methods that are not discussed here, but I have covered the most commonly used methods. I hope this has been a helpful summary for you.
You can find more information here:
MDN array.prototype.filter()
MDN array.prototype.map()
MDN array.prototype.reduce()
MDN array.prototype.forEach()
Posted on June 13, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.