Skip to main content

JavaScript Map, Filter, and Reduce

In functional programming, we often want to transform, select, or combine elements in a collection without modifying the original data. JavaScript provides three powerful array methods for these operations: map(), filter(), and reduce(). These methods help you write cleaner, more concise, and more readable code.

Introduction

The map(), filter(), and reduce() methods are higher-order functions that operate on arrays. They accept callback functions as arguments and apply these functions to each element in the array. These methods follow functional programming principles:

  • They don't mutate the original array
  • They return new values based on the original data
  • They rely on functions as first-class citizens

Let's explore each one in detail.

The Map Method

The map() method creates a new array by applying a function to each element in an existing array.

Syntax

javascript
const newArray = array.map(callback(currentValue[, index[, array]]) {
// return element for newArray
});

Basic Example

javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);

console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5] (original array unchanged)

Step-by-step Explanation

  1. The map() method iterates through each element of the numbers array
  2. For each element, it calls the arrow function number => number * 2
  3. Each result is added to a new array
  4. Once all elements are processed, the new array is returned

Practical Example: Formatting Data

javascript
const users = [
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' },
{ id: 3, name: 'Bob Johnson', email: '[email protected]' }
];

const usernames = users.map(user => user.name);
console.log(usernames); // ['John Doe', 'Jane Smith', 'Bob Johnson']

// Creating user display information
const userDisplayInfo = users.map(user => ({
displayName: user.name,
emailLink: `<a href="mailto:${user.email}">${user.email}</a>`
}));

console.log(userDisplayInfo);
/* Output:
[
{
displayName: 'John Doe',
emailLink: '<a href="mailto:[email protected]">[email protected]</a>'
},
{
displayName: 'Jane Smith',
emailLink: '<a href="mailto:[email protected]">[email protected]</a>'
},
{
displayName: 'Bob Johnson',
emailLink: '<a href="mailto:[email protected]">[email protected]</a>'
}
]
*/

The Filter Method

The filter() method creates a new array containing only elements that pass a specified test.

Syntax

javascript
const newArray = array.filter(callback(currentValue[, index[, array]]) {
// return true to keep element, false to filter it out
});

Basic Example

javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.filter(number => number % 2 === 0);

console.log(evenNumbers); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (original array unchanged)

Step-by-step Explanation

  1. The filter() method iterates through each element of the numbers array
  2. For each element, it calls the arrow function number => number % 2 === 0
  3. If the function returns true, the element is included in the new array
  4. If the function returns false, the element is excluded
  5. Once all elements are processed, the new array is returned

Practical Example: Filtering Data

javascript
const products = [
{ id: 1, name: 'Laptop', price: 999.99, inStock: true },
{ id: 2, name: 'Phone', price: 699.99, inStock: false },
{ id: 3, name: 'Tablet', price: 399.99, inStock: true },
{ id: 4, name: 'Watch', price: 199.99, inStock: true }
];

// Filter products that are in stock
const availableProducts = products.filter(product => product.inStock);
console.log(availableProducts);
/* Output:
[
{ id: 1, name: 'Laptop', price: 999.99, inStock: true },
{ id: 3, name: 'Tablet', price: 399.99, inStock: true },
{ id: 4, name: 'Watch', price: 199.99, inStock: true }
]
*/

// Filter products that are in stock AND less than $500
const affordableProducts = products.filter(product => product.inStock && product.price < 500);
console.log(affordableProducts);
/* Output:
[
{ id: 3, name: 'Tablet', price: 399.99, inStock: true },
{ id: 4, name: 'Watch', price: 199.99, inStock: true }
]
*/

The Reduce Method

The reduce() method executes a reducer function on each element of the array, resulting in a single output value.

Syntax

javascript
const result = array.reduce(callback(accumulator, currentValue[, index[, array]]) {
// return updated accumulator
}, initialValue);

Basic Example

javascript
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, current) => accumulator + current, 0);

console.log(sum); // 15 (1 + 2 + 3 + 4 + 5)

Step-by-step Explanation

  1. The reduce() method takes a callback function and an initial value (0 in this case)
  2. The callback receives two main arguments:
    • accumulator: The accumulated value from previous iterations
    • current: The current element being processed
  3. In the first iteration, accumulator is the initial value (0) and current is the first array element (1)
  4. The function returns 0 + 1 = 1, which becomes the new accumulator
  5. In the second iteration, accumulator is 1 and current is 2, resulting in 1 + 2 = 3
  6. This process continues until all elements are processed
  7. The final accumulator value is returned

Reduce without an Initial Value

If no initial value is provided, the first element of the array is used as the initial accumulator and the iteration starts from the second element:

javascript
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, current) => accumulator + current);
// First iteration: accumulator = 1, current = 2
// Second iteration: accumulator = 3, current = 3
// etc.

console.log(sum); // 15

Practical Examples

Creating an Object from an Array

javascript
const pets = ['dog', 'cat', 'dog', 'fish', 'cat', 'dog', 'fish'];

const petCounts = pets.reduce((counts, pet) => {
counts[pet] = (counts[pet] || 0) + 1;
return counts;
}, {});

console.log(petCounts);
// { dog: 3, cat: 2, fish: 2 }

Calculating Total Price with Tax

javascript
const cartItems = [
{ name: 'Laptop', price: 999.99, quantity: 1 },
{ name: 'Headphones', price: 99.99, quantity: 2 },
{ name: 'Mouse', price: 29.99, quantity: 1 }
];

const totalWithTax = cartItems.reduce((total, item) => {
const itemTotal = item.price * item.quantity;
return total + itemTotal;
}, 0) * 1.08; // Applying 8% tax

console.log(`Total with tax: $${totalWithTax.toFixed(2)}`);
// Total with tax: $1331.59

Chaining Array Methods

One of the most powerful aspects of map, filter, and reduce is the ability to chain them together for more complex operations.

Example: Calculate Average Price of In-stock Items

javascript
const products = [
{ id: 1, name: 'Laptop', price: 999.99, inStock: true },
{ id: 2, name: 'Phone', price: 699.99, inStock: false },
{ id: 3, name: 'Tablet', price: 399.99, inStock: true },
{ id: 4, name: 'Watch', price: 199.99, inStock: true },
{ id: 5, name: 'Headphones', price: 99.99, inStock: true }
];

const averageInStockPrice = products
.filter(product => product.inStock)
.map(product => product.price)
.reduce((avg, price, _, array) => avg + price / array.length, 0);

console.log(`Average price of in-stock items: $${averageInStockPrice.toFixed(2)}`);
// Average price of in-stock items: $424.99

Step-by-step Explanation of Chaining

  1. filter() creates a new array with only the in-stock products
  2. map() transforms that array into an array of just the prices
  3. reduce() calculates the average price by summing each price divided by the total count

Real-world Application: Data Processing Pipeline

Here's a real-world example of processing user data:

javascript
const users = [
{ id: 1, name: 'John', age: 25, active: true, purchases: [100, 200, 300] },
{ id: 2, name: 'Jane', age: 17, active: true, purchases: [50, 75] },
{ id: 3, name: 'Bob', age: 32, active: false, purchases: [250, 300, 150] },
{ id: 4, name: 'Mary', age: 28, active: true, purchases: [500] },
{ id: 5, name: 'Alex', age: 15, active: true, purchases: [25, 25, 30] }
];

// Get the total purchases of active adult users
const totalAdultActivePurchases = users
.filter(user => user.active && user.age >= 18) // Filter active adults
.map(user => user.purchases.reduce((sum, val) => sum + val, 0)) // Sum each user's purchases
.reduce((total, userTotal) => total + userTotal, 0); // Sum all user totals

console.log(`Total purchases by active adults: $${totalAdultActivePurchases}`);
// Total purchases by active adults: $1100

Summary

JavaScript's map(), filter(), and reduce() methods are powerful tools for functional programming:

  • map(): Transforms array elements into something new (one-to-one)
  • filter(): Selects elements that meet specific criteria
  • reduce(): Combines all elements into a single value or structure

These methods make your code:

  • More readable and expressive
  • Less prone to bugs (avoids mutations)
  • More maintainable (separates what to do from how to do it)
  • More concise (eliminates need for many for loops)

Additional Resources

Exercises

  1. Use map() to create an array of squares from an array of numbers.
  2. Use filter() to extract all prime numbers from an array of integers.
  3. Use reduce() to find the longest string in an array of strings.
  4. Chain these methods to find the sum of squares of positive numbers from a mixed array.
  5. Create a function that uses reduce() to group objects by a specified property.

Happy coding!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)