We're planting a tree for every job application! Click here to learn more

Cracking Filter, Map and Reduce - Practical Examples

Rafa Romero Dios

25 May 2021

•

4 min read

Cracking Filter, Map and Reduce - Practical Examples
  • JavaScript

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).

Introduction

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.

Filter

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)

Map

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)

Reduce

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}, []
);

Chaining function calls

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:

  • We filter by fruit
  • We map each fruit item to calculate its total price based on its price per weight and its weight.
  • Finally, we will reduce all this data to a total price:
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);

Closing

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!

Did you like this article?

Rafa Romero Dios

Software Engineer specialized in Front End. Back To The Future fan

See other articles by Rafa

Related jobs

See all

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Title

The company

  • Remote

Related articles

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

•

12 Sep 2021

JavaScript Functional Style Made Simple

JavaScript Functional Style Made Simple

Daniel Boros

•

12 Sep 2021

WorksHub

CareersCompaniesSitemapFunctional WorksBlockchain WorksJavaScript WorksAI WorksGolang WorksJava WorksPython WorksRemote Works
hello@works-hub.com

Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ

108 E 16th Street, New York, NY 10003

Subscribe to our newsletter

Join over 111,000 others and get access to exclusive content, job opportunities and more!

© 2024 WorksHub

Privacy PolicyDeveloped by WorksHub