While classes deal with objects and state, Functional Programming (FP) focuses on functions and immutability (not changing data directly). Modern JavaScript embraces FP, especially when dealing with data collections like arrays. This chapter covers the three most powerful array methods that are cornerstones of FP: map
, filter
, and reduce
.
Core FP Concepts
Immutability: Data should not be changed after creation. Instead, create new data structures.
Pure Functions: Functions that always return the same output for the same input, and have no side effects (like changing global variables or modifying external data).
Higher-Order Functions: Functions that take other functions as arguments (like map
, filter
, reduce
).
1. map()
: Transforming Data
The map()
method creates a new array populated with the results of calling a provided function on every element in the calling array. It is used for transformation.
JavaScript
const numbers = [1, 4, 9, 16];
// Goal: Create a new array where each number is doubled.
const doubled = numbers.map(num => num * 2);
console.log(doubled); // Output: [2, 8, 18, 32]
console.log(numbers); // Original array is unchanged (Immutability)
// Example with objects: Extracting specific properties
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];
const names = users.map(user => user.name);
console.log(names); // Output: ['Alice', 'Bob']
2. filter()
: Selecting Data
The filter()
method creates a new array containing all elements that pass a test implemented by the provided function. It is used for selection. The function must return a boolean (true
to keep, false
to discard).
JavaScript
const ages = [12, 18, 25, 6];
// Goal: Create an array of only users who are 18 or older.
const adults = ages.filter(age => age >= 18);
console.log(adults); // Output: [18, 25]
// Example with objects:
const products = [
{ name: 'Shirt', price: 50 },
{ name: 'Socks', price: 10 },
{ name: 'Jeans', price: 80 }
];
const expensiveProducts = products.filter(p => p.price > 40);
console.log(expensiveProducts); // Output: [{ name: 'Shirt', price: 50 }, { name: 'Jeans', price: 80 }]
3. reduce()
: Aggregating Data
The reduce()
method executes a reducer function (callback) on each element of the array, resulting in a single output value. It is used for aggregation (e.g., summing, counting, flattening).
The reducer function takes four arguments: (accumulator, currentValue, index, array)
. The accumulator
carries the result across each iteration.
JavaScript
const numbers = [1, 2, 3, 4];
// Goal: Calculate the sum of all numbers.
// 0 is the optional 'initialValue' of the accumulator.
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // Output: 10 (1+2+3+4)
// Example with objects: Counting items
const items = [{ cost: 10 }, { cost: 5 }, { cost: 15 }];
// Goal: Calculate the total cost.
const totalCost = items.reduce((acc, item) => acc + item.cost, 0);
console.log(totalCost); // Output: 30
Chaining Methods
A key advantage of FP is that since map
and filter
both return new arrays, you can easily chain these methods together to perform complex data manipulations in a highly readable way.
JavaScript
const transactions = [100, -50, 200, -30, 400];
// Goal: Sum up only the positive (deposits) transactions.
const totalDeposits = transactions
.filter(t => t > 0) // [100, 200, 400]
.reduce((total, deposit) => total + deposit, 0); // 700
console.log(totalDeposits); // Output: 700