DEV Community

Cover image for Understanding map(), filter() and reduce() in JavaScript
Aris Zagakos
Aris Zagakos

Posted on • Edited on

Understanding map(), filter() and reduce() in JavaScript

Table of Contents

  1. Introduction
  2. map()
  3. filter()
  4. reduce()
  5. Resources

Introduction

In the previous post we talked about First Class Functions and how JavaScript treat functions as a first-class-citizens.

Higher Orders Functions are functions that either take one or more functions as its arguments and/or return a function. This is a concept that was born out of functional programming. JavaScript, is a language that uses a lot of the functional programming concepts and Higher-Order Functions is one of them.

In this post we will discuss map(), filter() and reduce() that are some of the most well-known and easy to use Higher-Order Functions.

What Is Map?

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

Let's say that we want to create a new array that contains the double values of the numbers array.

A way to do it is to create the function double and call it for every element in the forEach.

Map written with a forEach

const numbers = [1, 2, 3];
const result = [];

const double = (number) => {
    return number * 2;
};

// Iterate over an array
numbers.forEach((number) => {
  result.push(double(number)); 
})

// [2 4 6]
console.log(result);
Enter fullscreen mode Exit fullscreen mode

And this is where map comes into play! Instead of calling the function manually, we can pass the function to map and javascript will call the function on every element for us!

Map written without a forEach

const numbers = [1, 2, 3];

const double = (number) => {
  return number * 2;
};

const result = numbers.map(double);

//[2,4,6]
console.log(result);
Enter fullscreen mode Exit fullscreen mode

Now let's see some other examples that we can use map

In the example below we create a new array using map that contains the full name of each person.

const people = [{
    first_name: "Michael",
    last_name: "Jordan"
}, {
    first_name: "LeBron",
    last_name: "James"
}, {
    first_name: "Stephen",
    last_name: "Curry"
}];

const fullNames = people.map((person) => {
    return `${person.first_name} ${person.last_name}`;
});

// [ 'Michael Jordan', 'LeBron James', 'Stephen Curry' ]
console.log(fullNames);
Enter fullscreen mode Exit fullscreen mode

In the example below we create a new array that contains the first two letters of each day.

const days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

const newDays = days.map((day) => {
    return day.substring(0,2);
});

// [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ]
console.log(newDays);
Enter fullscreen mode Exit fullscreen mode

When should you use a map?

  1. When you want to create a new array of the same length as the original array.
  2. When you want to transform an array of one thing into an array of another thing.

What Is Filter?

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

  • The call to filter() will return a new array.
  • The callback function used with filter should either return true or false.
    • true if the current element should appear in the new array.
    • false if the current element should NOT appear in the new array.

Let's say that we want to create a new array that contains the even numbers of the numbers array.

A way to do it is to create the function isEven to check if the number is even or not and call it for every element in the forEach.

Filter written with a forEach

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = [];

const isEven = (number) => {
    return number % 2 === 0;
  };

// 2. Iterate over an array
numbers.forEach((number) => {
  if (isEven(number)) {
    evenNumbers.push(number);
  }
});

// [ 2, 4, 6, 8, 10 ]
console.log(evenNumbers);
Enter fullscreen mode Exit fullscreen mode

Filter written without a forEach

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const isEven = (number) => {
  return number % 2 === 0;
};

const evenNumbers = numbers.filter(isEven);

// [ 2, 4, 6, 8, 10 ]
console.log(evenNumbers);
Enter fullscreen mode Exit fullscreen mode



Now let's see some other examples, that we can use filter

In the example below we create a new array that contains the people that their first_name has six or less characters.

const people = [{
    first_name: "Michael",
    last_name: "Jordan"
}, {
    first_name: "LeBron",
    last_name: "James"
}, {
    first_name: "Stephen",
    last_name: "Curry"
}];


const short = people.filter((person) => {
    return person.first_name.length <= 6;
});

// [ { first_name: 'LeBron', last_name: 'James' } ]
console.log(short);
Enter fullscreen mode Exit fullscreen mode

In the example below we have an array that contains the weekly days and we want to create a new array that will contain only the days that the number of their letters is less than 7.

const days = [
  'Sunday',
  'Monday',
  'Tuesday',
  'Wednesday',
  'Thursday',
  'Friday',
  'Saturday'
];
// create a new array with only the days that the length of their characters is less than 7
const shortDays = days.filter(day => {
  return day.length < 7;
});

// [ 'Sunday', 'Monday', 'Friday' ]
console.log(shortDays);
Enter fullscreen mode Exit fullscreen mode

When to use Filter:

  • When you want a new array of a different length, based on some condition that only some elements in the array satisfy.

What Is Reduce?

The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value. The accumulator can be anything (integer, string, object, etc.) and must be instantiated or passed when calling reduce().

  • The call to reduce() will return a single value.
  • The callback function used with reduce will get passed the accumulator value and an element in the array.
    • The accumulator value is the value returned from the last call to the callback function.
    • The callback function should always return a value to be used in the next callback.
  • The third argument to the reduce() function is the starting value for the accumulator.

Let's say that we want to calculate the sum of the numbers array.

Reduce written with a forEach

const numbers = [1,2,3,4,5,6];
let sum = 0;

// Iterate over the array
numbers.forEach((number) => {
    sum +=  number;
});

// 21
console.log(sum);
Enter fullscreen mode Exit fullscreen mode

Reduce written without a forEach

const numbers = [1,2,3,4,5,6];

// Iterate over the array
const sum = numbers.reduce((sum, number) => {
    sum += number;
    return sum; // Return the accumulator
}, 0);  // Initialize accumulator variable

// 21
console.log(sum);
Enter fullscreen mode Exit fullscreen mode

Now let's see some other examples, that we can use reduce.

In the example below we create a new object that contains as a key the name of the stock and as a value the frequency of the stock.

const stocks = ['TSLA', 'PLTR', 'TSLA', 'AAPL', 'PLTR', 'TSLA'];

const result = stocks.reduce((stockFreq, stock) => {
    if(stockFreq.hasOwnProperty(stock)) {
        stockFreq[stock]++;
    } else {
        stockFreq[stock] = 1;
    }

    return stockFreq;
}, {});

// { TSLA: 3, PLTR: 2, AAPL: 1 }
console.log(result);
Enter fullscreen mode Exit fullscreen mode

In the example below we create a new string that contains the first two letters of each day.

const days = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

const newDay = days.reduce((buffer ,day) => {
    buffer += day.substring(0,2);
    return buffer;
}, "");

// SuMoTuWeThFrSa
console.log(newDay);
Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (0)