Arrays are one of the most used data structures in Javascript, from storing basic data in our code to getting results from API calls. As Javascript developers were always working with arrays and carrying out some form of operation on them.
The .map(), .reduce() and .filter() are some of the lesser-known array methods released in ES6, that uses a more functional and cleaner approach to carry out array operations.
In this article, weβll be taking a detailed look at how these array methods work and how we can use them to carry out some basic operations.
Overview
First a brief look at what these array methods do.
The .map() method returns a new array where each element have gone through an operation of some kind.
The .filter() method returns a new array containing only array elements that passed a specific condition.
The .reduce() method reduces all the elements in the original to a single value.
These array methods are Higher Order Functions, meaning they take callback functions as parameters.
The .map() method
The .map() method returns a new array that contains the result of applying an operation on each of the original array elements.
The .map method accepts a callback function as a parameter and an important parameter for the callback function is the element parameter, the element parameter is processed by the callback function and returned an element to the new array.
Syntax for the .map() method
Array.map(function (element) {
//operation on element
})
//using arrow function
Array.map(element => {
//operation on element
})
Using the .map() method
let numbers = [24, 11, 8, 13]
const double = numbers.map(number=> score * 2)
console.log(double)
// outputs [ 48, 22, 16, 26 ]
When we run the code above. The .map() function loops through the numbers array, assigns the current element in iteration as number, carries out the operation number * 2, and then finally inserts this new value to the new array.
Note that the .map() method will always return an array of the same length as the original array.
For the rest of this tutorial, we'll be working with an array of objects, that contains the name, occupation and score of a group of employees.
const employees = [
{
name: "Peter",
score: 25,
occupation: "Engineer"
},
{
name: "Judy",
score: 30,
occupation: "Banker"
},
{
name: "Jarvis",
score: 40,
occupation: "Doctor"
},
{
name: "Paul",
score: 65,
occupation: "Engineer"
}
]
The .map() method can also be used to extract specific data from an array
With the .map() method, we can get the names of all the employees to a new array.
const names = employees.map(person => person.name)
console.log(names)
//returns ["Peter","Judy","Jarvis","Paul"]
More callback parameters
The .map() callback function can take more parameters that you might find useful when carrying out array operations.
Array.map((element, index, array) {operation})
The element parameter is used to access the current element in iteration.
The index returns the index of the current element in iteration
the array returns the complete original array.
I personally haven't seen any use case for the array parameter. If you have seen please comment below.
The .filter() Method
The .filter() returns a new array containing only elements that passed the condition passed in the callback function.
Syntax for the .filter() method
Array.filter(element => {
//condition
})
let numbers = [24, 11, 8, 13]
const filter = numbers.filter(number => number > 10)
console.log(filter)
// output [24,11,13]
When we run the code above the .filter() method loops through the numbers array, and checks if the current number is greater than 10, if true the number is added to the new array.
Using the .filter() method
We can use the .filter() method to get the array of employees who are engineers from our data above.
const allEngineers = people.filter(person => person.occupation === "Engineer")
console.log(allEngineers)
//Outputs
[
{
name: "Peter",
score: 25,
occupation: "Engineer"
},
{
name: "Paul",
score: 65,
occupation: "Engineer"
}
]
Optional callback parameters
The .filter() callback function just like the .map() can also take more than just the element parameter as an argument and they also serve the same purpose.
Array.filter((element, index, array) {condition})
The .reduce() method.
The .reduce() method is used to combine all the elements in an array to get a value. It evaluates all of the elements in the array to return a single value.
The .reduce() method is a little more complicated than the other two mentioned above because its callback function requires a specific parameter known as the βaccumulatorβ which holds the total value during the operation and returns it after the operation is completed. This "accumulator" parameter is used in the reducer function.
Syntax for .reduce() method
Array.reduce((accumulator, element) {
//reducer
}, initial value)
Using the .reduce method to get the sum of numbers.
let numbers= [24, 11, 8, 13]
const sum = numbers.reduce((sum, number) => {
return sum + number
}, 0)
console.log(sum)
// outputs 56
When the code above runs the .reduce() method first set the value of sum to 0 which was provided as the initial value and then loops through the array, on every iteration, it adds number to the value of sum, and after the last element returns sum which in our case is 56.
While the initial value might be optional it's always advisable to specify it, to avoid getting a TypeError in the case of an empty array. We get the error message below.
Uncaught TypeError: Reduce of empty array with no initial value
Chaining Methods
One of the pros of using these array methods is the ability to chain them. Since unlike the .forEach() method these array methods return a new array, we can chain them to get a combo method.
Chaining is combining array methods to perform operations on them and get a final return value.
Using chaining we can get the names of employees who scored above 35.
const passed= people.filter(person => person.score > 35)
.map(person => person.name)
console.log(passed)
// outputs ["Judy","Jarvis","Paul"]
In the code above the .filter() operation is carried out first on the array which returns an array of employees whose score is above 35 then the .map() method returns their name as the final value of the operation.
We can also get the sum of the scores of engineers only.
const engineersScore= people.filter(person => person.occupation === "Engineer") //return an array of engineers only
.map(person => person.score) //returns the array of engineers score
.reduce((sum, element) => sum + element) //sums up the score.
console.log(engineersScore)
//outputs 90
Conclusion
The best way to master new concepts is by using them. Try using these methods in place of the .forEach() when possible.
Feel free to comment below if you have any feedback and please share with other Javascript developers.
Let's Connect on Twitter
Top comments (10)
score and newScores ??
try this:
next:
score ??
Thanks a lot. I made some changes to the varible names and didn't change it everywhere.
I'll edit these these. Thanks
I always have to think hard before I use reduce, thats why I checked your example. Nice work.
Please Double check your code examples. Your example for the syntax of the reduce method is (syntactically) incorrect. You probably wanted to write "initialValue" instead of "inital value".
My favorite methods that I use in my work. Thanks for the article, it was useful to repeat. π
I wish people would stop referring to all functions that are passed in to other functions as 'callback functions'. It gives the misleading impression that they are somehow different or special in some way, when in fact they are just plain, ordinary functions. Giving them a fancy name just introduces unnecessary confusion to new developers, where there need not be any.
It only really makes sense to refer to them as 'callback' functions when they are passed into a function that performs an asynchronous task which will finish at some indeterminate time in the future - at which point, the function will be "called back" to tell you it's done. That is where the name comes from.
Wikipedia
Yeah, definitions vary... but I do feel it introduces unnecessary confusion - especially when not explained clearly (which I am indeed a little guilty of above). I see people refer to passed functions as 'callbacks' even when they are not called - i.e. in a function that wraps the passed function then returns the wrapped version - so confusion clearly exists. It is not as simple as 'every function passed to another function is a callback function', which I've heard variations of from many junior devs / interviewees.
The key part in the Wikipedia definition is:
for me it's just a function. Some see it differently. It's getting on my nerves that filter, map and reduce are talked about here every few days.....
Haha, yep. Dev should introduce a feature when you post to check if you're effectively reposting content from existing documentation, and attempt to discourage you from doing so.
It's super helpful broπ