DEV Community

Cover image for Use of filter(), map(), reduce() in JavaScript
Prosen Ghosh
Prosen Ghosh

Posted on • Updated on • Originally published at dev.to

Use of filter(), map(), reduce() in JavaScript

.filter(), .map(), .reduce(), can be operated separately or can be chained and used together. This method operates the array and transforms it into a new result.

Filter

filter() creates a new array of elements that pass the implemented test of the callback function with them.

const customers = [
    {
        name: "Mr. A",
        age: 21
    },
    {
        name: "Mr. B",
        age: 35
    },
    {
        name: "Mr. C",
        age: 18
    },
    {
        name: "Mr. D",
        age: 50
    },
    {
        name: "Mr. E",
        age: 25
    }
];

const result = customers.filter(function(elem){
    return elem.age >= 20 && elem.age <= 35;
});

console.log(
    JSON.stringify(result)
);
Enter fullscreen mode Exit fullscreen mode

Result

[{"name":"Mr. A","age":21},{"name":"Mr. B","age":35},{"name":"Mr. E","age":25}]
Enter fullscreen mode Exit fullscreen mode

Here we have filtered the customers array. We will get those customer returns whose age is between 20 to 35 (inclusive).

If we convert the above code to the fat arrow function of ES6, then the code will be as below.

const result = customers.filter((elem) => elem.age >= 20 && elem.age <= 35);

console.log(
    JSON.stringify(result)
);
Enter fullscreen mode Exit fullscreen mode

Result

[{"name":"Mr. A","age":21},{"name":"Mr. B","age":35},{"name":"Mr. E","age":25}]
Enter fullscreen mode Exit fullscreen mode

Map

map() creates a new array and calls a callback function for each element.

const customers = [
    {
        firstName: "John",
        lastName: "Smith"
    },
    {
        firstName: "Joe",
        lastName: "Smith"
    },
    {
        firstName: "Bob",
        lastName: "Smith"
    },
    {
        firstName: "Mike",
        lastName: "Smith"
    },
    {
        firstName: "Juan",
        lastName: "Smith"
    }
];

const result = customers.map(function(elem) {
    return {
        fullName: `${elem.firstName} ${elem.lastName}`
    }
});

console.log(
    JSON.stringify(result)
);
Enter fullscreen mode Exit fullscreen mode

Result

[{"fullName":"John Smith"},{"fullName":"Joe Smith"},{"fullName":"Bob Smith"},{"fullName":"Mike Smith"},{"fullName":"Juan Smith"}]
Enter fullscreen mode Exit fullscreen mode

Here customers have firstName and lastName. We can create each customer's fullName using map() method and it will return a new array.

If we convert the above code to the fat arrow function of ES6, then the code will be as below.

const result = customers.map((elem) => ({ fullName: `${elem.firstName} ${elem.lastName}` }));

console.log(
    JSON.stringify(result)
);
Enter fullscreen mode Exit fullscreen mode

Result

[{"fullName":"John Smith"},{"fullName":"Joe Smith"},{"fullName":"Bob Smith"},{"fullName":"Mike Smith"},{"fullName":"Juan Smith"}]
Enter fullscreen mode Exit fullscreen mode

We can return any type to the callback function after mapping (Array, Object, String, etc). Let's try a code

const customers = [
    {
        firstName: "John",
        lastName: "Smith"
    },
    {
        firstName: "Joe",
        lastName: "Smith"
    },
    {
        firstName: "Bob",
        lastName: "Smith"
    },
    {
        firstName: "Mike",
        lastName: "Smith"
    },
    {
        firstName: "Juan",
        lastName: "Smith"
    }
];

const result = customers.map(function(elem) {
    return elem.firstName.concat(" ", elem.lastName).length;
});

console.log(
    JSON.stringify(result)
); // [10,9,9,10,10]
Enter fullscreen mode Exit fullscreen mode

Here we concatenate the customer's firstName, lastName and return it's length.

Reduce

The reduce() method runs a reducer function for each element and returns a single result. The filter method includes a callback function and an initial value in it's argument.

const items = [
    {
        quantity: 1,
        price: 20
    },
    {
        quantity: 5,
        price: 200
    },
    {
        quantity: 7,
        price: 100
    }
];

const total = items.reduce(function(accumulator, currentValue){
    return accumulator + (currentValue.quantity * currentValue.price)
}, 0);

console.log(total); // 1720

Enter fullscreen mode Exit fullscreen mode

Here we have set 0 to the accumulator.

We get a single result total by multiplying the quantity and price of each item and adding it to the accumulator.

If we convert the above code to the fat arrow function of ES6, then the code will be as below.

const total = items.reduce(
    (accumulator, currentValue) => accumulator + (currentValue.quantity * currentValue.price),
    0
);

console.log(total); // 1720
Enter fullscreen mode Exit fullscreen mode

filter, map, reduce

Now we will try to combine filter, map, reduce.

Let me say a case before coding

We have orders data of an eCommerce business. We have to find out from those orders that the status of the order is ACCEPTED and the customer's age is between 20 to 30, how much money we have been able to sell to them.

We will first find the result using a function, then we will find the result by chaining those 3 methods.

const orders = [
    {
        customer: {
            id: "A1",
            age: 20
        },
        status: "ACCEPTED",
        items: [
            {
                quantity: 1,
                price: 20
            }
        ]
    },
    {
        customer: {
            id: "B1",
            age: 25
        },
        status: "ACCEPTED",
        items: [
            {
                quantity: 5,
                price: 200
            }
        ]
    },
    {
        customer: {
            id: "A1",
            age: 20
        },
        status: "REJECTED",
        items: [
            {
                quantity: 1,
                price: 20
            },
            {
                quantity: 5,
                price: 200
            },
            {
                quantity: 7,
                price: 100
            }
        ]
    },
    {
        customer: {
            id: "C1",
            age: 35
        },
        status: "ACCEPTED",
        items: [
            {
                quantity: 1,
                price: 10
            },
            {
                quantity: 5,
                price: 250
            },
            {
                quantity: 7,
                price: 50
            }
        ]
    },
    {
        customer: {
            id: "A1",
            age: 20
        },
        status: "ACCEPTED",
        items: [
            {
                quantity: 3,
                price: 200
            }
        ]
    }
];
Enter fullscreen mode Exit fullscreen mode

So first we have to find out the ACCEPTED order and all the customers between the age of 20 to 30.

const filterOrders = orders.filter(function(elem){
    return elem.status === "ACCEPTED" && elem.customer.age >= 20 && elem.customer.age <= 30;
});

console.log(filterOrders);
Enter fullscreen mode Exit fullscreen mode

Result

[{"customer":{"id":"A1","age":20},"status":"ACCEPTED","items":[{"quantity":1,"price":20}]},{"customer":{"id":"B1","age":25},"status":"ACCEPTED","items":[{"quantity":5,"price":200}]},{"customer":{"id":"A1","age":20},"status":"ACCEPTED","items":[{"quantity":3,"price":200}]}]
Enter fullscreen mode Exit fullscreen mode

Now we will calculate the total price of each order.

const mapOrders = mapOrders = filterOrders.map(
    function(elem) {
        return elem.items.reduce(function(accumulator, currentValue){
            return accumulator + (currentValue.quantity * currentValue.price);
        }, 0)
    }
);

console.log(mapOrders); // [20, 1000, 600]
Enter fullscreen mode Exit fullscreen mode

Now if we add all the values, we will get the result.

const totalSell = mapOrders.reduce(function(accumulator, currentValue){
    return accumulator + currentValue;
}, 0);

console.log(totalSell); // 1620

Enter fullscreen mode Exit fullscreen mode

Now we will try to do this whole thing by chaining the methods with ES6 fat arrow function.

const totalSell = orders
    .filter(elem => elem.status === "ACCEPTED" && elem.customer.age >= 20 && elem.customer.age <= 30)
    .map(elem => elem.items.reduce((accumulator, currentValue) => accumulator + (currentValue.quantity * currentValue.price), 0))
    .reduce((accumulator, currentValue) => accumulator + currentValue, 0);

console.log(totalSell); // 1620
Enter fullscreen mode Exit fullscreen mode

Discussion (0)