DEV Community

Marc Backes
Marc Backes

Posted on • Originally published at developer.blog

Get Started With The ES6 Array Methods .filter(), .map() and .reduce()

ES6 comes with many new features. One of which are a few very handy Array functions. The most popular for doing daily tasks are .filter(), .map, .reduce(). In this post, I'll cover each one with examples of first the "old" way, then with these new functions.

This post assumes you know about arrow functions. If you don't know what they are, don't worry. Read the first chapter of my blog post on array functions and you should be good to go for understanding what's going on here.

What they all have in common

All three functions were introduced in ES6 (ECMAScript 2015) and are functions that are applied to an Array.

Also, all of them as so-called higher-order functions. That means that they are a function which return functions as results or take other functions as parameters. In this case, it's the latter. That is very important to understand for this lesson.

On the inside, these functions run a forEach loop and then apply the passed function in one way or another to the data it's iterating.

.filter()

The easiest for me to understand was, .filter(). It does exactly what it says - It takes the existing array and returns a part of that array back, possibly skipping some value. Or in other words: Take out the items we don't want.

Having the following array of people with an age.

const people = [
    { name: 'John', age: 32},
    { name: 'Isabelle', age: 18},
    { name: 'Steve', age: 17},
    { name: 'Winston', age: 10},
    { name: 'Agnes', age: 82}
]
Enter fullscreen mode Exit fullscreen mode

Now we want to get only the people back that are of full age, or in other terms filter out the minors. Let's assume for this exercise we live in a country where 18 or higher means you're of full age.

If we were to write this statement without the .filter() function, it'd go something like this:

let adults = []
people.forEach(person => {
    if(person.age >= 18) {
        adults.push(person)
    }
})
Enter fullscreen mode Exit fullscreen mode

With the ES6 .filter() function if would look like this:

const adults = people.filter(person => person.age >= 18)

// Will outout the objects for John, Isabelle and Agnes...
console.log(adults)
Enter fullscreen mode Exit fullscreen mode

Let's break this down...

  • As a parameter we pass a function
  • That function (for this example) takes one parameter (here: person)
  • That parameter refers to the current element being iterated in filter()'s forEach.
  • The function we pass returns a boolean as a value. That boolean value indicates whether the current element is filtered out or not (true = stays in the array, false = is being skipped)
  • As condition for this boolean we have if the age of the person is higher or equal to 18.

Heads up! To make this blog post simpler, I won't explain all the parameters that can be passed. For further details on optional parameters, check out the MDN docu on filter().

.map()

.map() also returns an array as a result. But this time we won't filter anything, but fill the new array with data that's calculated from the original array.

Let's assume this array we have on degrees in degrees Celsius:

const celsiusArray = [ 21.5, 33.5, -7.1, 12.6 ]
Enter fullscreen mode Exit fullscreen mode

If we were to convert this to the same array, but with degrees Fahrenheit, we could do that traditionally like this:

let fahrenheitArray = []
celsiusArray.forEach(celsius => {
    fahrenheitArray.push((celsius * 9/5) + 32)
})
Enter fullscreen mode Exit fullscreen mode

If we want to write the same thing using .map(), it would look like this:

const fahrenheitArray = celsiusArray.map(celsius => (celsius * 9/5) + 32)
Enter fullscreen mode Exit fullscreen mode

Note, that unlike in the .filter() example, the array size of the original array and the output array is always the same when we use the .map() function.

Let's analyze what happened here...

  • As a parameter we pass a function
  • That function (for this example) takes one parameter (here: celsius)
  • That parameter refers to the current element being iterated in filter()'s forEach.
  • The function we pass returns a value of any type we want
  • That value is the one that will be inserted in the new array.

Heads up! To make this blog post simpler, I won't explain all the parameters that can be passed. For further details on optional parameters, check out the MDN docu on map().

.reduce()

This function is the only one of the three that don't return an array. Instead, it returns a single value.

This means, the functions uses the information from the array and calculates something out of it. What it calculates depends solely on the function we give it.

Let's assume this array of products consumed in a restaurant:

const foodOrder = [
    { name: 'Pizza Diavola', price: 15.9 },
    { name: 'Sparkling Water', price: 2.9 },
    { name: 'Tiramisu', price: 6.5 }
]
Enter fullscreen mode Exit fullscreen mode

If we want to calculate the sum of the food items display the total on the customer's ticket, including 17% VAT, we would do something like the following if we didn't knew about the .reduce() function:

let sum = 0
foodOrder.forEach(food => {
    sum += food.price
})
Enter fullscreen mode Exit fullscreen mode

With .reduce() it would look like this:

const total = foodOrder.reduce(( accumulator, food ) => accumulator + food.price, 0);
Enter fullscreen mode Exit fullscreen mode

Note, that unless like in the other two functions, .reduce() does not return an array, but a single value.

So what happens in the example above?

  • .reduce() iterates through our array and calls our function with every food item
  • The first item accumulator is the current "total" value the loop has calculated up to that point
  • food is the current items that's been iterating through
  • The return value of our passed function is whatever calulcation we want to do, working with the accumulator and currentValue (in this case add the two)
  • There would be just one hiccup: There must be an initial value in most times for this kind of calculations. Luckily ES6 provides us with an optional parameter (2nd in the .reduce() function)

Heads up! To make this blog post simpler, I won't explain all the parameters that can be passed. For further details on optional parameters, check out the MDN docu on reduce().

Oldest comments (4)

Collapse
 
pedroapfilho profile image
Pedro Filho

I created a repo last year to demonstrate some stuff about array methods: github.com/pedroapfilho/array-methods , feel free to check it out!

Collapse
 
themarcba profile image
Marc Backes

Oh that's so helpful. Do you mind if I attach that link to my blog post?

Collapse
 
nickytonline profile image
Nick Taylor • Edited

Sarah Edo created a really awesome tool called JavaScript Array Explorer.

GitHub logo sdras / array-explorer

⚡️ A resource to help figure out what JavaScript array method would be best to use at any given time

JavaScript Array Explorer

When I was first learning array methods, I spent a lot of time digging through the docs to find the appropriate one, and I had to search one by one. I made this resource to help people find the correct array method a bit more naturally. You can narrow down what you want to do and explore until you find what's most useful to you.

Check out the site here: arrayexplorer.netlify.com/

Or if you prefer codepen: codepen.io/sdras/full/gogVRX/

I realize that there are about a million ways that this resource can be set up, and some of the taxonomy is necessarily opionionated. I tried to focus on what I thought would have helped me learn the best, rather than industry standard delineations (mutator, accessor, iteration, for example). There are a lot of resources that already divide the methods this way, so if that style of learning suits you…

Collapse
 
pedroapfilho profile image
Pedro Filho

Of course not! Please do!