Monday 7 November 2022

Javascript: Use of .map(), .reduce(), and .filter()

.map()

Say you  receive an array containing multiple objects – each one representing a person. The thing you really need in the end, though, is an array containing only the id of each person.
There are multiple ways to achieve this. You might want to do it by creating an empty array, then using .forEach , .for(...of) or a simple .for()  to meet your goal.

// What you have
const teachers = [
{ id: 3, name: 'Alex' },
{ id: 34, name: 'Jhon' },
{ id: 23, name: 'Oggy' },
{ id: 87, name: 'Tom' }
];
// What you need [3, 34, 23, 87]


If we use .forEach()

const Ids = [];

teachers.forEach(function (teacher) {
Ids.push(teacher.id);
});

See how you have to create an empty array beforehand? 
Let’s see what it looks like when using .map()

If we use .map()

const teachersIds = teachers.map(teacher => teacher.id);

See how we don't need to initialise empty Ids array and also the code is more concise now.

Syntax is array.map(function(currentValue, index, arr), thisValue)

Parameters

ParameterDescription
function()Required.
A function to be run for each array element.
currentValueRequired.
The value of the current element.
indexOptional.
The index of the current element.
arrOptional.
The array of the current element.
thisValueOptional.
Default value undefined.
A value passed to the function to be used as its this value.

Keep in mind that the resulting array will always be the same length as the original array.




.reduce()

Just like .map(), .reduce() also runs a callback for each element of an array. What’s different here is that reduce passes the result of this callback (the accumulator) from one array element to the other.

The accumulator can be pretty much anything (integer, string, object, etc.) and must be instantiated or passed when calling .reduce().

let teachers = [{ id: 10, name: "Tom", years: 14 },
{ id: 2, name: "Wexley", years: 30 },
{ id: 41, name: "Lintra", years: 16 },
{ id: 99, name: "Asty", years: 22 }];

 With .reduce(), it’s pretty straightforward:

const totalYears = teachers.reduce((acc, teacher) => acc + teacher.years, 0);

I’ve set the starting value as 0. I could have also used an existing variable if necessary. After running the callback for each element of the array, reduce will return the final value of our accumulator


If I  say I want to find which pilot is the most experienced one of all, I can use reduce as well:

I named my accumulator oldest. My callback compares the accumulator to each teacher. If a teacher has more years of experience than oldest, then that teacher becomes the new oldest so that’s the one I return


const mostExpTeacher = teachers.reduce(function (oldest, teacher) {
return (teacher.years || 0) > teacher.years ? oldest : teacher;
}, {});

As you can see, using .reduce() is an easy way to generate a single value or object from an array.

Syntax is   array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

Parameters

ParameterDescription
function()Required.
A function to be run for each element in the array.
Reducer function parameters:
totalRequired.
The initialValue, or the previously returned value of the function.
currentValueRequired.
The value of the current element.
currentIndexOptional.
The index of the current element.
arrOptional.
The array the current element belongs to.
initialValueOptional.
A value to be passed to the function as the initial value.

The accumulated result from the last call of the callback function.



.filter()

What if you have an array, but only want some of the elements in it? That’s where .filter() comes in! Here’s our data:

const pilots = [{id: 2, name: "Wedge Antilles", faction: "Rebels"},
{id: 8, name: "Ciena Ree", faction: "Empire"},
{id: 40, name: "Iden Versio", faction: "Empire"},
{id: 66, name: "Thane Kyrell", faction: "Rebels"}];

Say we want two arrays now: one for rebel pilots, the other one for imperials. With .filter() it couldn’t be easier!

const rebels = pilots.filter(pilot => pilot.faction === "Rebels");
const empire = pilots.filter(pilot => pilot.faction === "Empire");

Basically, if the callback function returns true, the current element will be in the resulting array. If it returns false, it won’t be.Returns array containing the elements that pass the test. If no elements pass the test it returns an empty array.

Syntax is array.filter(function(currentValue, index, arr), thisValue)


Parameters

ParameterDescription
function()Required.
A function to run for each array element.
currentValueRequired.
The value of the current element.
indexOptional.
The index of the current element.
arrOptional.
The array of the current element.
thisValueOptional. Default undefined
A value passed to the function as its this value.






No comments:

Post a Comment