Master the JavaScript Array filter() method with detailed syntax, 6+ code examples with output, comparison with find() and forEach(), common mistakes, interview questions, and FAQ. Beginner-friendly guide in English with detailed explanations.
The JavaScript filter() method is one of the most powerful and commonly used array methods. It creates a new array containing only those elements that pass a test (provided as a callback function). The original array is never modified — making filter() a pure, non-mutating method.
Whether you're building a search feature, cleaning up API data, or removing unwanted items from a list — filter() is your go-to tool.
Simple Explanation: The filter() method creates a new array containing only those elements that pass our condition. The original array remains unchanged.
Syntax
const newArray = array.filter(callback(element, index, array), thisArg);
Parameters
| Parameter | Required | Description |
|---|
callback | ✅ Yes | Function that tests each element. Must return true to keep, false to discard. |
element | ✅ Yes | The current element being processed in the array. |
index | ❌ Optional | The index of the current element in the array. |
array | ❌ Optional | The original array on which filter() was called. |
thisArg | ❌ Optional | Value to use as this when executing the callback. |
Return Value
- Returns: A new array containing elements that pass the test.
- If no elements pass: Returns an empty array
[] (never undefined or null). - Mutates original: ❌ NO — always creates a fresh array.
Code Examples
Example 1: Basic Filtering — Numbers
The most common use case: filtering numbers based on a condition.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Keep only even numbers
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log("Even numbers:", evenNumbers);
// Keep numbers greater than 5
const greaterThanFive = numbers.filter(num => num > 5);
console.log("Greater than 5:", greaterThanFive);
// Keep odd numbers less than 7
const oddAndSmall = numbers.filter(num => num % 2 !== 0 && num < 7);
console.log("Odd and < 7:", oddAndSmall);
// Original array is unchanged
console.log("Original:", numbers);
Even numbers: [2, 4, 6, 8, 10]
Greater than 5: [6, 7, 8, 9, 10]
Odd and < 7: [1, 3, 5]
Original: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Example 2: Filtering Objects — Real-World Product Data
In real applications, you'll most often filter arrays of objects.
const products = [
{ name: "Laptop", price: 75000, category: "electronics", inStock: true },
{ name: "T-Shirt", price: 599, category: "clothing", inStock: true },
{ name: "Smartphone", price: 45000, category: "electronics", inStock: false },
{ name: "Jeans", price: 1999, category: "clothing", inStock: true },
{ name: "Headphones", price: 2999, category: "electronics", inStock: true },
{ name: "Sneakers", price: 4500, category: "footwear", inStock: false }
];
// Filter by category
const electronics = products.filter(p => p.category === "electronics");
console.log("Electronics:", electronics.map(p => p.name));
// Filter by multiple conditions: affordable + in stock
const affordableAndAvailable = products.filter(
p => p.price < 5000 && p.inStock
);
console.log("Affordable & Available:", affordableAndAvailable.map(p => p.name));
// Filter OUT unavailable products (keep only in-stock)
const available = products.filter(p => p.inStock);
console.log("In Stock:", available.map(p => p.name));
// Filter by price range
const midRange = products.filter(p => p.price >= 1000 && p.price <= 10000);
console.log("Mid-range (₹1000-₹10000):", midRange.map(p => p.name));
Electronics: ["Laptop", "Smartphone", "Headphones"]
Affordable & Available: ["T-Shirt", "Jeans", "Headphones"]
In Stock: ["Laptop", "T-Shirt", "Jeans", "Headphones"]
Mid-range (₹1000-₹10000): ["Jeans", "Headphones", "Sneakers"]
Example 3: Filter with Index Parameter
The second parameter of the callback gives you access to the element's index.
const fruits = ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape"];
// Keep elements at even indices (0, 2, 4, 6...)
const evenIndexed = fruits.filter((_, index) => index % 2 === 0);
console.log("Even indices:", evenIndexed);
// Keep only the first 3 elements
const firstThree = fruits.filter((_, index) => index < 3);
console.log("First three:", firstThree);
// Skip the first 2, keep the rest
const skipTwo = fruits.filter((_, index) => index >= 2);
console.log("After skipping 2:", skipTwo);
// Keep every 3rd element (index 0, 3, 6...)
const everyThird = fruits.filter((_, index) => index % 3 === 0);
console.log("Every 3rd:", everyThird);
Even indices: ["Apple", "Cherry", "Elderberry", "Grape"]
First three: ["Apple", "Banana", "Cherry"]
After skipping 2: ["Cherry", "Date", "Elderberry", "Fig", "Grape"]
Every 3rd: ["Apple", "Date", "Grape"]
Example 4: Chaining filter() + map() — Data Pipeline
Chaining filter() with map() and reduce() creates powerful data processing pipelines.
const employees = [
{ name: "Amit", department: "Engineering", salary: 95000, active: true },
{ name: "Priya", department: "Marketing", salary: 72000, active: true },
{ name: "Rahul", department: "Engineering", salary: 120000, active: true },
{ name: "Sneha", department: "Engineering", salary: 85000, active: false },
{ name: "Vikram", department: "Marketing", salary: 110000, active: true },
{ name: "Anjali", department: "Engineering", salary: 140000, active: true }
];
// Pipeline: Active Engineers → Names → Sorted by salary (high to low)
const topEngineers = employees
.filter(emp => emp.department === "Engineering" && emp.active)
.sort((a, b) => b.salary - a.salary)
.map(emp => `${emp.name} (₹${emp.salary.toLocaleString()})`);
console.log("Top Active Engineers:", topEngineers);
// Pipeline: filter → reduce (total marketing salary)
const marketingBudget = employees
.filter(emp => emp.department === "Marketing" && emp.active)
.reduce((total, emp) => total + emp.salary, 0);
console.log("Marketing salary budget:", `₹${marketingBudget.toLocaleString()}`);
// Pipeline: filter → map → join (email list)
const activeEmails = employees
.filter(emp => emp.active)
.map(emp => `${emp.name.toLowerCase()}@company.com`)
.join(", ");
console.log("Active emails:", activeEmails);
Top Active Engineers: ["Anjali (₹1,40,000)", "Rahul (₹1,20,000)", "Amit (₹95,000)"]
Marketing salary budget: ₹1,82,000
Active emails: amit@company.com, priya@company.com, rahul@company.com, vikram@company.com, anjali@company.com
Example 5: Custom Search Filter — Building a Search Feature
A practical pattern for building search functionality in apps.
const articles = [
{ id: 1, title: "Learn JavaScript Basics", tags: ["javascript", "beginner"], author: "Amit" },
{ id: 2, title: "Advanced React Patterns", tags: ["react", "advanced"], author: "Priya" },
{ id: 3, title: "JavaScript Array Methods", tags: ["javascript", "arrays"], author: "Rahul" },
{ id: 4, title: "CSS Grid Layout Guide", tags: ["css", "layout"], author: "Sneha" },
{ id: 5, title: "Node.js REST API Tutorial", tags: ["nodejs", "api"], author: "Amit" }
];
// Search function: searches title, tags, and author
function searchArticles(articles, query) {
const q = query.toLowerCase().trim();
if (!q) return articles; // return all if query is empty
return articles.filter(article =>
article.title.toLowerCase().includes(q) ||
article.tags.some(tag => tag.includes(q)) ||
article.author.toLowerCase().includes(q)
);
}
// Search by topic
console.log("Search 'javascript':");
console.log(searchArticles(articles, "javascript").map(a => a.title));
// Search by author
console.log("\nSearch 'amit':");
console.log(searchArticles(articles, "amit").map(a => a.title));
// Search by tag
console.log("\nSearch 'api':");
console.log(searchArticles(articles, "api").map(a => a.title));
// No results
console.log("\nSearch 'python':");
console.log(searchArticles(articles, "python").map(a => a.title));
Search 'javascript':
["Learn JavaScript Basics", "JavaScript Array Methods"]
Search 'amit':
["Learn JavaScript Basics", "Node.js REST API Tutorial"]
Search 'api':
["Node.js REST API Tutorial"]
Search 'python':
[]
Example 6: Removing Falsy Values
filter(Boolean) is a clean shorthand for removing all falsy values from an array.
const messyData = [0, 1, "", "hello", null, undefined, NaN, false, 42, "world", true];
// Remove ALL falsy values using Boolean as callback
const truthyOnly = messyData.filter(Boolean);
console.log("Truthy only:", truthyOnly);
// Remove only null and undefined (keep 0, false, "")
const noNullish = messyData.filter(item => item !== null && item !== undefined);
console.log("No null/undefined:", noNullish);
// Remove empty strings only
const noEmptyStrings = messyData.filter(item => item !== "");
console.log("No empty strings:", noEmptyStrings);
// Practical: Clean user input array
const userInputs = [" ", "John", "", " Doe ", null, "Smith"];
const cleanInputs = userInputs
.filter(input => input !== null && input !== undefined)
.map(input => input.trim())
.filter(input => input.length > 0);
console.log("Clean inputs:", cleanInputs);
Truthy only: [1, "hello", 42, "world", true]
No null/undefined: [0, 1, "", "hello", NaN, false, 42, "world", true]
No empty strings: [0, 1, "hello", null, undefined, NaN, false, 42, "world", true]
Clean inputs: ["John", "Doe", "Smith"]
Example 7: Removing Duplicates with filter()
Using filter() with indexOf() is a classic technique for removing duplicates.
const numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];
// Keep first occurrence only (remove duplicates)
const unique = numbers.filter((item, index, arr) => arr.indexOf(item) === index);
console.log("Unique:", unique);
// Find ONLY the duplicate values
const duplicates = numbers.filter((item, index, arr) => arr.indexOf(item) !== index);
console.log("Duplicates (all):", duplicates);
// Unique duplicate values
const uniqueDuplicates = [...new Set(duplicates)];
console.log("Unique duplicates:", uniqueDuplicates);
// Remove duplicates from array of objects (by property)
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 1, name: "Alice (duplicate)" },
{ id: 3, name: "Charlie" },
{ id: 2, name: "Bob (duplicate)" }
];
const uniqueUsers = users.filter((user, index, self) =>
index === self.findIndex(u => u.id === user.id)
);
console.log("Unique users:", uniqueUsers.map(u => `${u.id}: ${u.name}`));
Unique: [3, 1, 4, 5, 9, 2, 6]
Duplicates (all): [1, 5, 3, 5]
Unique duplicates: [1, 5, 3]
Unique users: ["1: Alice", "2: Bob", "3: Charlie"]
filter() vs find() vs forEach()
Understanding when to use filter(), find(), or forEach() is crucial.
| Feature | filter() | find() | forEach() |
|---|
| Returns | New array of ALL matches | First matching element | undefined (nothing) |
| When no match | Empty array [] | undefined | Still runs on all elements |
| Stops early? | ❌ No (checks ALL) | ✅ Yes (stops at first) | ❌ No (runs on ALL) |
| Mutates original? | ❌ No | ❌ No | ❌ No (but you can mutate inside) |
| Purpose | Get all matching items | Get one specific item | Execute side effects |
| Chainable? | ✅ Yes | ❌ No (returns single value) | ❌ No (returns undefined) |
const scores = [45, 72, 88, 55, 91, 66, 78];
// filter() → ALL elements that pass
const passing = scores.filter(score => score >= 60);
console.log("All passing scores:", passing);
// find() → FIRST element that passes
const firstPassing = scores.find(score => score >= 60);
console.log("First passing score:", firstPassing);
// forEach() → Execute action, return nothing
const results = [];
scores.forEach(score => {
if (score >= 60) results.push(score >= 80 ? "A" : "B");
});
console.log("Grades for passing:", results);
// When to use which:
// Need ALL matches? → filter()
// Need FIRST match? → find()
// Need to DO something? → forEach()
All passing scores: [72, 88, 91, 66, 78]
First passing score: 72
Grades for passing: ["B", "A", "A", "B", "B"]
Tip: If you need all matching elements → filter(). If you need only the first matching element → find(). If you need to perform an action on every element → forEach().
Common Mistakes
Mistake 1: Forgetting to Return a Value
// ❌ WRONG: No return statement (implicit return is undefined → falsy)
const numbers = [1, 2, 3, 4, 5];
const wrong = numbers.filter(num => {
num > 3; // Missing return!
});
console.log("Wrong (no return):", wrong);
// ✅ CORRECT: Explicit return
const correct = numbers.filter(num => {
return num > 3;
});
console.log("Correct (with return):", correct);
// ✅ CORRECT: Arrow function shorthand (implicit return)
const alsoCorrect = numbers.filter(num => num > 3);
console.log("Also correct (shorthand):", alsoCorrect);
Wrong (no return): []
Correct (with return): [4, 5]
Also correct (shorthand): [4, 5]
Mistake 2: Using filter() When You Need find()
// ❌ WRONG: Using filter to get a single item
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
const wrongWay = users.filter(u => u.id === 2)[0]; // Scans ALL elements
console.log("filter()[0]:", wrongWay?.name);
// ✅ CORRECT: Use find() for single item (stops at first match)
const rightWay = users.find(u => u.id === 2);
console.log("find():", rightWay?.name);
filter()[0]: Bob
find(): Bob
Mistake 3: filter(Boolean) Removes Valid Zeroes
// ❌ PROBLEM: filter(Boolean) removes 0 which may be valid
const temperatures = [0, 15, -3, 22, 0, 8];
const wrongClean = temperatures.filter(Boolean);
console.log("filter(Boolean) — loses zeroes:", wrongClean);
// ✅ CORRECT: Be specific about what to remove
const correctClean = temperatures.filter(temp => temp !== null && temp !== undefined);
console.log("Specific filter — keeps zeroes:", correctClean);
filter(Boolean) — loses zeroes: [15, -3, 22, 8]
Specific filter — keeps zeroes: [0, 15, -3, 22, 0, 8]
Mistake 4: Mutating Objects Inside filter()
// ❌ BAD PRACTICE: Mutating objects inside filter callback
const items = [
{ name: "Apple", price: 100, discount: false },
{ name: "Banana", price: 40, discount: false },
{ name: "Cherry", price: 200, discount: false }
];
const expensive = items.filter(item => {
if (item.price > 50) {
item.discount = true; // ❌ Side effect! Mutates original
return true;
}
return false;
});
console.log("Filtered:", expensive.map(i => i.name));
console.log("Original mutated!:", items.map(i => `${i.name}: discount=${i.discount}`));
// ✅ CORRECT: Keep filter pure, use map for transformations
const items2 = [
{ name: "Apple", price: 100 },
{ name: "Banana", price: 40 },
{ name: "Cherry", price: 200 }
];
const expensiveWithDiscount = items2
.filter(item => item.price > 50)
.map(item => ({ ...item, discount: true })); // New objects!
console.log("Pure result:", expensiveWithDiscount);
Filtered: ["Apple", "Cherry"]
Original mutated!: ["Apple: discount=true", "Banana: discount=false", "Cherry: discount=true"]
Pure result: [{name: "Apple", price: 100, discount: true}, {name: "Cherry", price: 200, discount: true}]
Mistake 5: Comparing Objects/Arrays by Reference
// ❌ WRONG: Objects are compared by reference, not value
const data = [{ x: 1 }, { x: 2 }, { x: 3 }];
const target = { x: 2 };
const wrong = data.filter(item => item === target);
console.log("Reference comparison:", wrong); // Empty! Different objects
// ✅ CORRECT: Compare by property values
const correct = data.filter(item => item.x === target.x);
console.log("Value comparison:", correct);
// ❌ WRONG: Same issue with arrays
const matrix = [[1, 2], [3, 4], [1, 2]];
const wrong2 = matrix.filter(row => row === [1, 2]);
console.log("Array reference:", wrong2); // Empty!
// ✅ CORRECT: Compare contents
const correct2 = matrix.filter(row => row[0] === 1 && row[1] === 2);
console.log("Array values:", correct2);
Reference comparison: []
Value comparison: [{x: 2}]
Array reference: []
Array values: [[1, 2], [1, 2]]
Key Takeaways
- Always returns a new array —
filter() never modifies the original array. It's a pure, non-mutating method.
- Callback must return truthy/falsy — Elements with a
true (truthy) return value are kept; false (falsy) values are skipped.
filter(Boolean) removes falsy values — A quick shorthand, but be careful: it also removes 0, "", and false which may be valid data.
- Use
find() for single items — If you only need the first match, find() is more efficient because it stops searching after the first hit.
- Chaining is powerful —
.filter().map().reduce() creates elegant data processing pipelines without intermediate variables.
- Keep callbacks pure — Don't mutate objects inside
filter(). Use map() to create transformed copies.
- Returns
[] when nothing matches — Never returns undefined or null, so you can safely chain .length, .map(), etc. on the result.
- Index parameter is useful — The second callback parameter gives you the element's position for index-based filtering.
- Does NOT stop early —
filter() always processes every element in the array, even after finding matches. For early exit, use find() or some().
- Great for search features — Combining
filter() with includes(), startsWith(), or regex creates powerful search/autocomplete functionality.
Interview Questions
Q1: What does filter() return when no elements match the condition?
Answer: filter() returns an empty array [] — never undefined, null, or false. This makes it safe to chain further array methods on the result without checking for null.
const nums = [1, 2, 3];
const result = nums.filter(n => n > 100);
console.log(result); // []
console.log(result.length); // 0
console.log(Array.isArray(result)); // true
Q2: Does filter() mutate the original array?
Answer: No. filter() is a non-mutating (pure) method. It always creates and returns a brand-new array. The original array remains completely unchanged. However, if the array contains objects, both the original and filtered arrays will reference the same objects in memory (shallow copy).
const original = [1, 2, 3, 4, 5];
const filtered = original.filter(n => n > 3);
console.log("Filtered:", filtered);
console.log("Original:", original);
console.log("Same array?", original === filtered);
Filtered: [4, 5]
Original: [1, 2, 3, 4, 5]
Same array? false
Q3: What is the difference between filter() and find()?
Answer:
| Aspect | filter() | find() |
|---|
| Returns | Array of ALL matches | FIRST matching element |
| No match | [] (empty array) | undefined |
| Stops early | ❌ No | ✅ Yes |
| Use case | Get all items matching criteria | Get one specific item |
const ages = [16, 22, 18, 30, 14, 25];
const allAdults = ages.filter(age => age >= 18);
console.log("filter (all adults):", allAdults);
const firstAdult = ages.find(age => age >= 18);
console.log("find (first adult):", firstAdult);
filter (all adults): [22, 18, 30, 25]
find (first adult): 22
Q4: How does filter(Boolean) work and what are its pitfalls?
Answer: Boolean is a built-in function that converts any value to true or false. When passed as the filter callback, it removes all falsy values: 0, "", null, undefined, NaN, and false.
Pitfall: It removes 0 and "" which may be valid data in your application.
const mixed = [0, 1, "", "text", null, undefined, NaN, false, 42];
// Boolean removes ALL falsy values
console.log("filter(Boolean):", mixed.filter(Boolean));
// Safer: remove only null/undefined
console.log("Nullish only:", mixed.filter(v => v != null));
filter(Boolean): [1, "text", 42]
Nullish only: [0, 1, "", "text", NaN, false, 42]
Q5: Write a function to filter an array of objects by multiple dynamic criteria.
Answer:
function filterByCriteria(items, criteria) {
return items.filter(item =>
Object.entries(criteria).every(([key, value]) => {
if (typeof value === "function") return value(item[key]);
if (Array.isArray(value)) return value.includes(item[key]);
return item[key] === value;
})
);
}
const products = [
{ name: "Laptop", price: 75000, brand: "Dell", inStock: true },
{ name: "Phone", price: 25000, brand: "Samsung", inStock: true },
{ name: "Tablet", price: 35000, brand: "Apple", inStock: false },
{ name: "Monitor", price: 15000, brand: "Dell", inStock: true }
];
// Dynamic filter: Dell products, in stock, price under 50000
const result = filterByCriteria(products, {
brand: "Dell",
inStock: true,
price: (p) => p < 50000
});
console.log("Filtered:", result.map(p => `${p.name} (₹${p.price})`));
// Filter by multiple brands
const multiBrand = filterByCriteria(products, {
brand: ["Dell", "Apple"],
inStock: true
});
console.log("Multi-brand:", multiBrand.map(p => p.name));
Filtered: ["Monitor (₹15000)"]
Multi-brand: ["Laptop", "Monitor"]
FAQ (Frequently Asked Questions)
1. Can filter() work on strings?
filter() is an array method and cannot be called directly on strings. However, you can convert a string to an array first, filter it, then join it back.
const sentence = "Hello World 123";
// Remove all digits from a string
const lettersOnly = sentence.split("").filter(char => isNaN(char) || char === " ").join("");
console.log(lettersOnly);
// Keep only vowels
const vowels = "aeiouAEIOU";
const onlyVowels = sentence.split("").filter(char => vowels.includes(char)).join("");
console.log(onlyVowels);
2. Is filter() slower than a for loop?
For most applications, the performance difference is negligible. filter() has a tiny overhead due to function calls, but it provides:
- Better readability
- Fewer bugs (no off-by-one errors)
- Immutability (no accidental mutations)
For arrays with millions of elements where performance is critical, a for loop may be marginally faster. For typical web applications (arrays under 10,000 elements), always prefer filter().
const largeArray = Array.from({ length: 100000 }, (_, i) => i);
console.time("filter");
const filtered = largeArray.filter(n => n % 2 === 0);
console.timeEnd("filter");
console.time("for loop");
const result = [];
for (let i = 0; i < largeArray.length; i++) {
if (largeArray[i] % 2 === 0) result.push(largeArray[i]);
}
console.timeEnd("for loop");
console.log("Both same length:", filtered.length === result.length);
filter: 5.2ms
for loop: 3.8ms
Both same length: true
3. Can I use async/await inside filter()?
No. filter() does not work with async callbacks because it expects a synchronous truthy/falsy return value. An async function always returns a Promise (which is truthy), so all elements will pass.
// ❌ WRONG: async filter doesn't work as expected
const ids = [1, 2, 3, 4, 5];
// This WON'T work — all Promises are truthy!
const wrong = ids.filter(async (id) => {
return id > 3; // Returns Promise, which is always truthy
});
console.log("Wrong (async filter):", wrong); // All elements kept!
// ✅ CORRECT: Use Promise.all + map, then filter
async function asyncFilter(arr, predicate) {
const results = await Promise.all(arr.map(predicate));
return arr.filter((_, index) => results[index]);
}
// Usage (simulated):
const syncResult = ids.filter(id => id > 3);
console.log("Correct approach:", syncResult);
Wrong (async filter): [1, 2, 3, 4, 5]
Correct approach: [4, 5]
4. What is the difference between filter() and reduce() for filtering?
Both can filter, but they serve different purposes. filter() is specifically designed for filtering and is more readable. reduce() can filter AND transform in a single pass.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// filter() — clean and clear intent
const evensFilter = numbers.filter(n => n % 2 === 0);
console.log("filter():", evensFilter);
// reduce() — can filter + transform in one pass
const doubledEvens = numbers.reduce((acc, n) => {
if (n % 2 === 0) acc.push(n * 2); // filter + transform
return acc;
}, []);
console.log("reduce() (filter+double):", doubledEvens);
// Equivalent with filter + map (two passes but more readable)
const doubledEvens2 = numbers.filter(n => n % 2 === 0).map(n => n * 2);
console.log("filter()+map():", doubledEvens2);
filter(): [2, 4, 6, 8, 10]
reduce() (filter+double): [4, 8, 12, 16, 20]
filter()+map(): [4, 8, 12, 16, 20]
5. Does filter() work on sparse arrays (arrays with holes)?
filter() skips empty slots in sparse arrays. It only calls the callback on indices that actually have values assigned to them.
// Sparse array (has empty slots)
const sparse = [1, , , 4, , 6]; // indices 1, 2, 4 are empty
console.log("Sparse length:", sparse.length);
// filter skips empty slots entirely
const filtered = sparse.filter(item => true); // keep everything
console.log("After filter:", filtered);
console.log("Filtered length:", filtered.length);
// This means filter can remove holes from sparse arrays
const withHoles = new Array(5);
withHoles[1] = "hello";
withHoles[3] = "world";
console.log("With holes:", withHoles);
const noHoles = withHoles.filter(() => true);
console.log("No holes:", noHoles);
Sparse length: 6
After filter: [1, 4, 6]
Filtered length: 3
With holes: [undefined, "hello", undefined, "world", undefined]
No holes: ["hello", "world"]
Quick Reference Cheat Sheet
┌──────────────────────────────────────────────────────────┐
│ filter() Method — Quick Reference │
├──────────────────────────────────────────────────────────┤
│ │
│ Basic: arr.filter(n => n > 0) │
│ Objects: arr.filter(obj => obj.active) │
│ Remove falsy: arr.filter(Boolean) │
│ Remove nullish: arr.filter(v => v != null) │
│ Remove duplicates:arr.filter((v,i,a) => a.indexOf(v)===i)│
│ By index: arr.filter((_, i) => i % 2 === 0) │
│ Multi-condition: arr.filter(v => v > 0 && v < 100) │
│ Chain + map: arr.filter(v => v > 0).map(v => v*2) │
│ Search: arr.filter(v => v.includes(query)) │
│ Nested property: arr.filter(v => v.addr.city === "X") │
│ │
│ Returns: New array (never mutates original) │
│ No match: [] (empty array, never undefined) │
│ Async: ❌ Does NOT support async callbacks │
│ Stops early: ❌ No (always scans full array) │
│ │
└──────────────────────────────────────────────────────────┘
*Last updated: June 12, 2026 | Written by WoHoTech*