DEV Community

Cover image for JavaScript Array methods: Filter, Map, Reduce, and Sort
Ivana
Ivana

Posted on

JavaScript Array methods: Filter, Map, Reduce, and Sort

Functions are a very important part of JavaScript, and you will use them all the time. In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. There are several ways to define functions, the most common one is to define functions with a function declaration. Example:

function calcRectArea(width, height) {
  return width * height;
}

console.log(calcRectArea(5, 6));
//-------> Output: 30
Enter fullscreen mode Exit fullscreen mode

Term "callback"

When we pass a function expression (an anonymous function) or the pointer (variable name, declared function name) to a function as an argument, the passed function is called a callback. Since the receiving function will execute, or call that function at a later time; that is, it will call it back, it is called a callback.

Let's learn more about Array methods: Filter, Map, Reduce, and Sort

Alt Text

Arrays provide a lot of methods. JavaScript already has methods built into its Array data type. Follows the examples of how to use it.

Use .filter() to filter an Array

filter() returns a new array of filter elements that meet a certain condition. The filter() method creates a new array with all elements that pass the test implemented by the provided function.
filter() does not execute the function for array elements without values and doesn't change the original array.

Syntax:

array.filter(function(currentValue, index, arr), thisValue)
Enter fullscreen mode Exit fullscreen mode

function(currentValue, index,arr) is required.

A function to be run for each element in the array, function arguments are:
currentValue- required, the value of the current element
index - optional, the array index of the current element
arr - optional, the array object the current element belongs to.
thisValue- optional. A value to be passed to the function to be used as its "this" value. If this parameter is empty, the value "undefined" will be passed as its "this" value.

Example

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
//-------> Output: Array ["exuberant", "destruction", "present"]

//-------> Output: ["exuberant", "destruction", "present"]
Enter fullscreen mode Exit fullscreen mode

Example:

[10, 20, 30, 40].filter(function() {
    return true;
  }) //=> [10, 20, 30, 40] (map, basically)

  [10, 20, 30, 40].filter(function(e) {
    return e < 30;
  }) //=> [10, 20]

  [10, 20, 30, 40].filter(function(e, index) {
    return index % 2 === 0;
  }) //=> [10, 30] (elements with an even-numbered index)
Enter fullscreen mode Exit fullscreen mode

Example:

const myArray = [
  { id: 1, name: "Mark" },
  { id: 2, name: "Sam" },
  { id: 3, name: "Sandy" },
  { id: 4, name: "Mark" },
]

myArray.filter(element => element.name === "Mark")
//-------> Output : 0:{id: 1, name: "Mark"},
//                  1:{id: 4, name: "Mark"}

Enter fullscreen mode Exit fullscreen mode

Use .map() to transform an Array

The map() method calls a callback function on every element of an array and returns a new array that contains the results.

The map() method takes two named arguments, the first one is required whereas the second one is optional.

Syntax:

const newArr = oldArr.map(function(currentValue, index, array) {
  // Do stuff with currentValue (index and array are optional)
});
Enter fullscreen mode Exit fullscreen mode

newArr - the new array that is returned
oldArr - the old array being operated on. This array will not be changed
currentValue - the current value being processed
index - the current index of the value being processed
array - the original array

Example:

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
//-------> Output: [2, 8, 18, 32]
Enter fullscreen mode Exit fullscreen mode

Example:

[10, 20, 30, 40].map(function(a) {
  return a * 2;
}); 
//-------> Output: [20, 40, 60, 80]
Enter fullscreen mode Exit fullscreen mode

ES6 Example:

const arr = [1, 2, 3, 4];

const newArray = arr.map(element => {
  return element * 2;
});

const newArrayOneLiner = arr.map(element => element * 2);

console.log(arr); // [1, 2, 3, 4]
console.log(newArray); // [2, 4, 6, 8]
console.log(newArrayOneLiner); // [2, 4, 6, 8]
Enter fullscreen mode Exit fullscreen mode

Use .reduce() to reduce an Array to a value

The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value. The reduce() method executes a provided function for each value of the array (from left-to-right).
Alt Text
The return value of the function is stored in an accumulator (result/total).

Note: reduce() does not execute the function for array elements without values.

This method does not change the original array.

Syntax:

array.reduce( function(total, currentValue, currentIndex, arr), 
initialValue )
Enter fullscreen mode Exit fullscreen mode

This method accepts five parameters:

function(total, currentValue, index, arr): It is the required parameter and used to run for each element of the array. It contains four-parameter which are listed below:
total: It is a required parameter and used to specify the initialValue, or the previously returned value of the function.
currentValue: It is a required parameter and used to specify the value of the current element.
currentIndex: It is an optional parameter and used to specify the array index of the current element.
arr: It is an optional parameter and used to specify the array object the current element belongs to.
initialValue: It is an optional parameter and used to specify the value to be passed to the function as the initial value.

[10, 20, 30, 40].reduce(function(memo, i) { return memo + i }) //=> 100
[10, 20, 30, 40].reduce(function(memo, i) { return memo + i }, 100) //=> 200
Enter fullscreen mode Exit fullscreen mode

Example

Subtract the numbers in the array, starting from the beginning:

var numbers = [125, 20, 25, 30];

document.getElementById("demo").innerHTML = numbers.reduce(myFunc);

function myFunc(total, num) {
  return total - num;
}
//=> 50

Enter fullscreen mode Exit fullscreen mode

Let's see how .reduce() works. The callback would be invoked four times, with the arguments and return values in each call being as follows:

[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator + currentValue
})
Enter fullscreen mode Exit fullscreen mode
callback iteration accumulator currentValue currentIndex array returnValue
first call 0 1 1 [0, 1, 2, 3, 4] 1
second call 1 2 2 [0, 1, 2, 3, 4] 3
third call 3 3 3 [0, 1, 2, 3, 4] 6
fourth call 6 4 4 [0, 1, 2, 3, 4] 10

Use sort()

The sort() method sorts the elements of an array in place and returns the sorted array.

Syntax

arr.sort([compareFunction])
Enter fullscreen mode Exit fullscreen mode

Paramaters:
compareFunction is optional. It specifies a function that defines the sort order.
firstEl, the first element for comparison.
secondEl, the second element for comparison.

To sort an array of objects by the values of the object’s properties, you use the sort() method and provide a comparison function that determines the order of objects.

Example

Suppose that you have an array of students objects as follows:

let students = [
    {
        firstName: 'Johnny',
        lastName: 'Lee',
        age: 20,
    },

    {
        firstName: 'Anna',
        lastName: 'Zax',
        age: 19,

    },

    {
        firstName: 'Zion',
        lastName: 'Sanches',
        age: 22,

    }
];
Enter fullscreen mode Exit fullscreen mode

The following statement snippet sorts the students array by ages in ascending order:

students.sort((a, b) => {
    return a.age - b.age;
});
Enter fullscreen mode Exit fullscreen mode

where to display the students, you can use the forEach() method:

studetns.forEach((e) => {
    console.log(`${e.firstName} ${e.lastName} ${e.age}`);
});
Enter fullscreen mode Exit fullscreen mode

Output:

Anna Zax 19
Jonny Lee 20
Zion Sanchez 22
Enter fullscreen mode Exit fullscreen mode

To sort the students by ages in descending order, you just need to reverse the order in the comparison function like this:

students.sort((a, b) => b.age - a.age);

students.forEach((e) => {
    console.log(`${e.firstName} ${e.lastName} ${e.age}`);
});
Enter fullscreen mode Exit fullscreen mode

output:

Zion Sanchez 22
Jonny Lee 20
Anna Zax 19
Enter fullscreen mode Exit fullscreen mode

Conclusion

We saw how map(), filter(), reduce() and sort() can ease the life of a developer by reducing the number of unnecessary explicit loops and empty array declarations. Try replacing your for loops with these state-of-the-art functions whenever you get a chance. More documentation can be found here.

To connect please check my Github, LinkedIn or Twitter.

Thank you for reading!

Oldest comments (4)

Collapse
 
arvindsridharan profile image
arvindsridharan

Very nicely explained. Good work!

A post on Javascript closure and call back would be of great help.

Collapse
 
ivanadokic profile image
Ivana

Thank you @arvindsridharan !

Collapse
 
aminnairi profile image
Amin

Very nice and clear article, thanks Ivana.

Are you using the JavaScript Markdown syntax highlight in all of your code snippets? It looks like they are not rendered as JavaScript snippets but as plain text from my side of view.

Otherwise, one thing I would like to add about this infamous Array.prototype.reduce method is that it can be used as a base to create all of the Array.prototype.* goodies you have talked about and even the every or some methods.

"use strict";

const filterMap = (filterAndUpdate, items) => {
  //             |
  //             |
  //             |
  //             V
  return items.reduce((previousItems, item) => {
    const updated = filterAndUpdate(item);

    if (updated !== false) {
      return [
        ...previousItems,
        updated
      ];
    }

    return previousItems;
  }, []);
};

const users = [
  {id: 1, username: "johndoe", email: "john@doe.com"},
  {id: 2, username: "janedoe", email: "jane@doe.com"},
  {id: 3, username: "linustorvalds", email: "ltorvalds@linux.com"},
];

const ids = filterMap(({email, id}) => email.includes("doe") && id, users);

console.log(ids); // [1, 2]
Enter fullscreen mode Exit fullscreen mode
Collapse
 
burgercousin profile image
Pentium_4

thx a lot!