Rafa Romero Dios
25 May 2021
•
4 min read
Today we're gonna talk about three very important methods for manipulating arrays that were introduced in ES2015: filter, map, and reduce.
The goal of this article is not to go deep into these methods APIs (you can do it by yourself by doing a bit of googling) but show how to use them in practical cases. It is common to search for info about how to use these methods and not to find examples that really show useful cases, but too much literature.
The idea is to show the method signature, then a basic example just to illustrate how this method works, and then some use cases. Finally, we will see an example chaining the three methods' calls (filter + map + reduce).
These methods allow us to manipulate arrays in a functional way, which means that we will manipulate the array through functions that will be passed to the methods as arguments. These functions define the criteria to be applied to each element of the array.
These methods have become very popular and in most cases allow us to avoid using loops like for
and forEach
.
The filter method is probably the most intuitive method of the three. We are able to filter our array given a criteria. This criteria will be defined by a function that will be passed as a filter method parameter.
A new array will be returned containing the elements that fulfill the defined criteria.
Below you have the method signature: MDN Web Docs
var newArray = arr.filter(callback(currentValue[, index[, array]])[, thisArg])
And here we can find a simple example
const numbers = [1, 2, 3, 4, 5]
// return items that are equal to two
const filterResult = numbers.filter(number => number === 2)
Let's see now some other examples:
const numbers = [1, 2, 3, 4, 5]
// return those items that are multiple of two
const multipleOfTwo = numbers.filter(number => number % 2 === 0)
// return those items that are greater than two
const greaterThanTwo = numbers.filter(number => number > 2 === 0)
// return those items that are lower than two
const greaterThanTwo = numbers.filter(number => number < 2 === 0)
const names = ['Marty', 'Doc', 'Jennifer', 'George', 'Lorraine']
// return those characters that matches some value
const mainCharacters = names.filter(name => name === 'Marty' || name === 'Doc')
// return those characters that contains letter "R"
const nameContainsLetter = names.filter(name => name.includes('r'))
const cars = [{
brand: 'Tesla',
color: 'black',
type: 'electric'
},
{
brand: 'BMW',
color: 'Blue',
type: 'electric'
},
{
brand: 'Ferrari',
color: 'red',
type: 'fuel'
}]
// return those cars that are electric
const electricCars = cars.filter(car => car.type === 'electric')
// return those cars that are NOT electric
const nonElectricCars = cars.filter(car => car.type !== 'electric')
const referenceCar = {
brand: 'Tesla',
type: 'electric'
}
// return those cars that are electric by passing a different 'this' object
function isElectricCar(car) {
return car.type === this.type
}
const electricCars = cars.filter(isElectricCar, referenceCar)
The map method allows us to apply an operation over each item of a given array. The operation to be applied will be defined by a function that will be passed as a map method parameter.
Below you have the method signature: MDN Web Docs
var newArray = arr.map(function callback(currentValue, index, array) { ... }[, thisArg])
And here we can find a simple example where we obtain an array with twice the value of each item
const numbers = [1, 2, 3, 4, 5]
// map: return twice the value of each item
const mapResult = numbers.map(number => number*2)
Let's see now some other examples:
const names = ['marty', 'doc', 'jennifer', 'george', 'lorraine']
// return all names uppercased
const uppercasedNames = names.map(name => name.toUpperCase())
// return all names capitalized
const capitalizedNames = names.map(name => name[0].toUpperCase() + name.substr(1));
// return the domain name given a email list
const emailList = ['marty@gmail.com', 'doc@yahoo.com', 'jennifer@outlook.com', 'george@mydomain.com', 'lorraine@icloud.com']
const domainName = emailList.map(email => email.substr(email.indexOf('@') + 1));
const homekitStatus = [{
place: 'Living Room',
status: false,
type: 'bulb'
},
{
place: 'Bathroom',
status: false,
type: 'bulb'
},
{
place: 'Kitchen',
status: true,
type: 'bulb'
}]
// return an array with updated status
homekitStatus = homekitStatus.map(device => { return {place: device.place, status: !device.status, type: device.type}})
const referenceDomain = {
domain: 'gmail',
type: 'free'
}
// return the domain name given a email list by passing a different 'this' objet
const emailList = ['marty@gmail.com', 'doc@yahoo.com', 'jennifer@outlook.com', 'george@mydomain.com', 'lorraine@icloud.com']
function getDomain(email) {
return email.substr(email.indexOf('@') + 1));
}
const gmailEmails = emailList.map(getDomain, referenceDomain)
Last but not least, we have the reduce method. The reduce method allows us to convert an array into a simple value based on its content. Its content will be converted based on a function passed as a parameter.
Below you have the method signature: MDN Web Docs
var reducedValue = arr.reduce(callback(acumulador, valorActual[, Ãndice[, array]])[, valorInicial])
And here we can find a simple example where we obtain the sum of the items of an array
const numbers = [1, 2, 3, 4, 5]
// get the total sum of items of the array
const total = numbers.reduce((accumulator, number) => accumulator + number)
Let's see some other examples:
// get the total sum of items of the array passing an initial value as accumulator (10)
const numbers = [1, 2, 3, 4, 5]
const total = numbers.reduce((accumulator, number) => accumulator + number, 10)
// flattening an array
const composedArray = [[0,1], [2,3], [4,5]];
const flattenArray = composedArray.reduce((accumulator, array) =>
accumulator.concat(array),
);
// Get the list of avengers names: Getting a new array based on data of other arrays
const Avengers = [{
name: 'IronMan',
power: 'Technology',
},
{
name: 'Thor',
power: 'Godness',
},
{
name: 'Captain America',
power: 'strength',
}]
const avengerNames = avengers.reduce((accumulator, avengerCharacter) => {
accumulator.push(avengerCharacter.name)
return accumulator}, []
);
Finally, we thought that it would be really useful to have an example where the three methods are used chaining one to each other at a time. For that, we have prepared an array example where we have a shopping cart and we want to have the total price of the fruits bought.
To do that:
const shoppingCart = [{
name: "banana",
pricePerWeight: 2,
weight: 2,
type: 'fruit'
}, {
name: "water",
quantity: 12,
type: 'drink'
}, {
name: "beer",
quantity: 6,
type: 'drink'
}, {
name: "apple",
pricePerWeight: 5,
weight: 2.5,
type: 'fruit'
}, {
name: "tshirt",
quantity: 1,
type: 'clothes'
}, {
name: "watermelon",
pricePerWeight: 3,
weight: 5,
type: 'fruit'
}, {
name: "melon",
pricePerWeight: 4,
weight: 4,
type: 'fruit'
}, {
name: "iPhone",
quantity: 1,
type: 'electronic'
}, {
name: "pinneaple",
pricePerWeight: 4.5,
weight: 3.5,
type: 'fruit'
}, {
name: "peach",
pricePerWeight: 3,
weight: 2.5,
type: 'fruit'
}, {
name: "pear",
pricePerWeight: 2,
weight: 1.5,
type: 'fruit'
}, {
name: "jeans",
quantity: 2,
type: 'clothes'
}, ]
const totalPrice = shoppingCart.filter(item => item.type === 'fruit').map(item => item.pricePerWeight * item.weight).reduce((accumulator, item) => accumulator + item);
I hope that you found all these examples useful and with these use cases you can understand how these popular array methods work better than before!
Rafa Romero Dios
Software Engineer specialized in Front End. Back To The Future fan
See other articles by Rafa
Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ
108 E 16th Street, New York, NY 10003
Join over 111,000 others and get access to exclusive content, job opportunities and more!