What Are Array Methods?
Array methods are built-in JavaScript functions that perform operations on arrays. Instead of writing loops manually, these methods provide cleaner, more readable ways to transform, filter, and analyze data.
Think of array methods like:
- Food Processor Analogy: Array methods are like different attachments on a food processor. Each attachment has a specific function—chopping, slicing, or blending— just as each array method performs a specific operation on data.
-
Assembly Line Analogy:
Array methods work like workers on an assembly line.
Each worker performs one task on every item as it passes by,
similar to how methods like
map(),filter(), orforEach()process each element in an array. -
Specialized Tools Analogy:
Array methods are specialized tools.
You choose the right tool for the job—use
filter()to select items,reduce()to combine values, andfind()to locate a specific element.
Why Learn Array Methods?
- Make code cleaner: Less verbose than traditional loops, resulting in more readable and maintainable code.
- Prevent bugs: Reduce the risk of accidentally modifying the wrong variable or state.
- Are chainable: Allow multiple operations to be combined elegantly in a single expression.
- Show intent: Descriptive method names clearly explain what the code is doing.
- Are functional: Enable functional programming patterns such as immutability and pure functions.
Map: Transform Every Item
Use map when: You need to transform all items in an array (convert, calculate, format)
let newArray = array.map(function(item, index, array) {
return transformedItem;
});
// With arrow function (common)
let newArray = array.map(item => transformedItem);
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5] (original unchanged)
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5] (original unchanged)
- Map goes through each number
- Multiplies it by 2
- Puts the result in a new array
- The original array stays the same
let prices = [19.99, 29.99, 9.99, 49.99];
let formatted = prices.map(price => "$" + price.toFixed(2));
console.log(formatted);
// ["$19.99", "$29.99", "$9.99", "$49.99"]
Filter: Keep Only Items That Pass a Test
The filter() method creates a new array containing only the elements
that pass a test (return true).
Use filter() when:
You need to select specific items from an array based on a condition.
let newArray = array.filter(function(item, index, array) {
return condition; // true to keep, false to exclude
});
// With arrow function
let newArray = array.filter(item => condition)
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6, 8, 10]
let people = [
{ name: "Alice", age: 17 },
{ name: "Bob", age: 22 },
{ name: "Charlie", age: 15 },
{ name: "Diana", age: 30 }
];
let adults = people.filter(person => person.age >= 18);
console.log(adults);
// [
// { name: "Bob", age: 22 },
// { name: "Diana", age: 30 }
// ]
Example 3: Filter Strings by Length
let words = ["hi", "hello", "hey", "goodbye", "greetings"];
let shortWords = words.filter(word => word.length <= 5);
console.log(shortWords); // ["hi", "hello", "hey"]
let longWords = words.filter(word => word.length > 5);
console.log(longWords); // ["goodbye", "greetings"]
Reduce: Combine All Items Into One Value
The reduce() method reduces an array to a single value by applying
a function that combines all elements step by step.
Use reduce() when:
You need to calculate a single value from an array, such as a sum, product,
or concatenated result.
let result = array.reduce(function(accumulator, currentItem, index, array) {
return updatedAccumulator;
}, initialValue);
// With arrow function
let result = array.reduce((acc, item) => acc + item, initialValue);
let numbers = [1, 2, 3, 4, 5]; let sum = numbers.reduce((total, num) => total + num, 0); console.log(sum); // 15
let numbers = [5, 12, 8, 130, 44, 3];
let max = numbers.reduce((maximum, num) => {
return num > maximum ? num : maximum;
});
let nested = [[1, 2], [3, 4], [5, 6]];
let flat = nested.reduce((result, array) => result.concat(array), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]
Find, Some, and Every: Search and Test Arrays
Find: Get First Item That Matches
The find() method returns the first element in an array
that satisfies a given condition.
let numbers = [5, 12, 8, 130, 44];
let found = numbers.find(num => num > 10);
console.log(found); // 12 (first number > 10)
let notFound = numbers.find(num => num > 200);
console.log(notFound); // undefined
Some: Check If At Least One Passes
The some() method tests if at least one element passes the condition.
let users = [
{ name: "Alice", isAdmin: false },
{ name: "Bob", isAdmin: true },
{ name: "Charlie", isAdmin: false }
];
let hasAdmin = users.some(user => user.isAdmin);
console.log("Has admin:", hasAdmin); // Has admin: true
let allAdmins = users.every(user => user.isAdmin);
console.log("All admins:", allAdmins); // All admins: false
Every: Check If All Pass
The every() method tests whether all elements in an array
pass a given condition and returns a boolean value.
let numbers = [2, 4, 6, 8, 10];
let allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // true
let allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true
let allLarge = numbers.every(num => num > 5);
console.log(allLarge); // false (2 and 4 are not > 5)
let formFields = [
{ name: "username", value: "john_doe", valid: true },
{ name: "email", value: "john@example.com", valid: true },
{ name: "password", value: "12345", valid: false }
];
let isFormValid = formFields.every(field => field.valid);
console.log("Form valid:", isFormValid); // Form valid: false
let hasErrors = formFields.some(field => !field.valid);
console.log("Has errors:", hasErrors); // Has errors: true
forEach: Execute Function for Each Item
The forEach() method executes a provided function once for
each element in an array. Unlike map(), it does not return
a new array.
Use forEach when: You want to perform an action for each item (logging, updating UI, side effects)
array.forEach(function(item, index, array) {
// Do something with item
});
// With arrow function
array.forEach(item => {
// Do something
});
let fruits = ["apple", "banana", "orange"];
fruits.forEach(fruit => {
console.log(fruit);
});
// Output:
// apple
// banana
// orange
let numbers = [1, 2, 3, 4, 5];
let sum = 0;
numbers.forEach(num => {
sum += num;
});
Chaining Array Methods: Combine Multiple Operations
Method chaining allows you to combine multiple array methods in sequence, enabling powerful and readable data transformations in a single flow.
<ul>
<li><strong>Cleaner code:</strong> One readable statement instead of many temporary variables.</li>
<li><strong>More efficient:</strong> Processes data in a streamlined sequence.</li>
<li><strong>More readable:</strong> Each transformation step is clear and easy to follow.</li>
<li><strong>Functional style:</strong> Easier to reason about and maintain.</li>
</ul>
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Get even numbers, then double them
let result = numbers
.filter(num => num % 2 === 0)
.map(num => num * 2);
console.log(result); // [4, 8, 12, 16, 20]
Without chaining (harder to read):
let evens = numbers.filter(num => num % 2 === 0);
let doubled = evens.map(num => num * 2);
console.log(doubled);
let rawData = [" Alice ", "", " Bob ", null, " Charlie ", undefined];
// Clean data: remove empty/null, trim whitespace, uppercase
let cleaned = rawData
.filter(item => item) // Remove falsy values
.map(item => item.trim()) // Remove spaces
.map(item => item.toUpperCase()); // Uppercase
console.log(cleaned); // ["ALICE", "BOB", "CHARLIE"]
Real-World Examples: Putting It All Together
Example 1: E-commerce Product Filter
let scores = [85, 92, 78, 95, 88, 76, 90, 84];
let stats = {
total: scores.reduce((sum, score) => sum + score, 0),
average: scores.reduce((sum, score) => sum + score, 0) / scores.length,
highest: scores.reduce((max, score) => score > max ? score : max),
lowest: scores.reduce((min, score) => score < min ? score : min),
passing: scores.filter(score => score >= 80).length,
failing: scores.filter(score => score < 80).length
};
console.log(stats);
// {
// total: 688,
// average: 86,
// highest: 95,
// lowest: 76,
// passing: 6,
// failing: 2
// }
let transactions = [
{ type: "income", amount: 1000, category: "salary" },
{ type: "expense", amount: 50, category: "food" },
{ type: "expense", amount: 100, category: "transport" },
{ type: "income", amount: 200, category: "freelance" },
{ type: "expense", amount: 75, category: "food" }
];
let summary = {
totalIncome: transactions
.filter(t => t.type === "income")
.reduce((sum, t) => sum + t.amount, 0),
totalExpense: transactions
.filter(t => t.type === "expense")
.reduce((sum, t) => sum + t.amount, 0),
foodExpense: transactions
.filter(t => t.category === "food")
.reduce((sum, t) => sum + t.amount, 0)
};
summary.balance = summary.totalIncome - summary.totalExpense;
console.log(summary);
// {
// totalIncome: 1200,
// totalExpense: 225,
// foodExpense: 125,
// balance: 975
// }
// ❌ WRONG - No return statement
let doubled = [1, 2, 3].map(num => {
num * 2; // Missing return!
});
console.log(doubled); // [undefined, undefined, undefined]
// ✅ CORRECT - Explicit return
let doubled = [1, 2, 3].map(num => {
return num * 2;
});
// ✅ EVEN BETTER - Implicit return
let doubled = [1, 2, 3].map(num => num * 2);
// ❌ WRONG - Modifying original
let numbers = [1, 2, 3];
let doubled = numbers.map(num => {
numbers[0] = 100; // Bad! Mutating original
return num * 2;
});
// ✅ CORRECT - Don't mutate original
let numbers = [1, 2, 3];
let doubled = numbers.map(num => num * 2);
// Original unchanged: [1, 2, 3]
// ❌ LESS IDEAL - forEach with push
let doubled = [];
[1, 2, 3].forEach(num => doubled.push(num * 2));
// ✅ BETTER - Use map
let doubled = [1, 2, 3].map(num => num * 2);