Chaining Array Methods
Each array method you have learned returns a value — a new array or a single result. Because filter and map return arrays, you can call another method on that result immediately. This is method chaining.
A simple chain
Section titled “A simple chain”const expenses = [ { id: 1, description: 'Coffee', amount: 4.50, category: 'Food', date: '2024-01-15' }, { id: 2, description: 'Bus pass', amount: 30.00, category: 'Transport', date: '2024-01-14' }, { id: 3, description: 'Lunch', amount: 12.75, category: 'Food', date: '2024-01-15' }, { id: 4, description: 'Gym membership', amount: 45.00, category: 'Health', date: '2024-01-10' }, { id: 5, description: 'Dinner out', amount: 38.20, category: 'Food', date: '2024-01-16' },];
// Total amount spent on Foodconst foodTotal = expenses .filter(e => e.category === 'Food') .reduce((acc, e) => acc + e.amount, 0);
console.log(foodTotal.toFixed(2)); // '55.45'Each line in the chain gets its own line for readability. The chain reads like English: “from expenses, keep only Food items, then sum their amounts.”
sort reorders the array in place (it mutates) and returns the same array. Always pass a comparator function — the default sort converts items to strings, which gives wrong results with numbers.
// Ascending by amountconst byAmount = [...expenses].sort((a, b) => a.amount - b.amount);The spread ([...expenses]) creates a copy first — since sort mutates, you protect the original by sorting a copy.
The comparator receives two items a and b:
- Return a negative number →
asorts beforeb - Return a positive number →
bsorts beforea - Return
0→ order unchanged
// Descending by amountconst byAmountDesc = [...expenses].sort((a, b) => b.amount - a.amount);
// Alphabetical by descriptionconst byName = [...expenses].sort((a, b) => a.description.localeCompare(b.description));
// Chronological by dateconst byDate = [...expenses].sort((a, b) => new Date(a.date) - new Date(b.date));some and every
Section titled “some and every”These two methods return a boolean answer about the array.
some returns true if at least one item passes the test:
const hasLargeExpense = expenses.some(e => e.amount > 40);console.log(hasLargeExpense); // true (Gym membership is $45)every returns true if all items pass the test:
const allUnder100 = expenses.every(e => e.amount < 100);console.log(allUnder100); // trueBoth short-circuit — some stops at the first true, every stops at the first false. Use them for validation checks.
A real BudgetBuddy chain
Section titled “A real BudgetBuddy chain”This function returns the top-3 most expensive food expenses, formatted for display:
function getTopFoodExpenses(expenses) { return expenses .filter(e => e.category === 'Food') .sort((a, b) => b.amount - a.amount) .slice(0, 3) .map(e => `${e.description}: $${e.amount.toFixed(2)}`);}
console.log(getTopFoodExpenses(expenses));// ['Dinner out: $38.20', 'Lunch: $12.75', 'Coffee: $4.50']Reading it top to bottom: keep Food items → sort largest first → take the first three → format as strings. Each step is one focused method call.
When chaining gets messy
Section titled “When chaining gets messy”Chaining is not always the right choice. If a chain is hard to read, break it into named variables:
// Hard to read as a one-linerconst result = expenses.filter(e => e.category === 'Food' && e.amount > 10).sort((a, b) => b.amount - a.amount).map(e => e.description);
// Better — each step is namedconst foodExpenses = expenses.filter(e => e.category === 'Food' && e.amount > 10);const sorted = [...foodExpenses].sort((a, b) => b.amount - a.amount);const descriptions = sorted.map(e => e.description);The named-variable version is easier to debug — you can log each step independently.
Exercise
Section titled “Exercise”Using the expenses array from this lesson:
- Get all expenses with
amount > 10, sorted ascending by amount, returning just thedescriptionof each. - Check: does any expense cost more than
$50? (Usesome.) - Check: do all expenses have a
categoryproperty? (Useevery.) - Write a function
getCategoryTotal(expenses, category)that returns the total amount for a given category, using chaining. - Sort a copy of the array alphabetically by
descriptionand log the descriptions.
- Method chaining calls a method on the return value of the previous method — readable when each step fits on one line.
sortmutates — sort a copy with[...array].sort()to protect the original.- The sort comparator returns negative, positive, or zero to control order.
somereturnstrueif at least one item passes;everyreturnstrueif all items pass.- When a chain becomes hard to read, break it into named intermediate variables.