filter()
filter()
Level 4 — Iteration & Array Methods Creates a new array with all elements that pass the test implemented by the provided function.
1. Prerequisites
- Array — An ordered list of values.
- Truthy / Falsy — Values that evaluate to boolean true or false.
2. Term Category
Array Method / Functional Programming (Universal: Works everywhere): filter() is a fundamental concept in this technology stack. Level 4 — Iteration & Array Methods
3. Explanation
(1) Design Motivation — "Why did we design this?"
Often, you have a massive dataset but you only care about a specific subset of it: finding all users over age 18, finding all products under $50, or removing all empty strings from a list.
Like map(), doing this manually with a for loop requires creating an empty array, writing an if statement, pushing to the new array, and returning it. filter() was designed to abstract this. You provide a callback function that acts as a true/false test. filter() automatically builds a new array, runs your test on every item, and only copies the items into the new array if they pass the test (return a "Truthy" value).
(2) Reality Metaphor
filter() is like a nightclub bouncer holding a guest list. A massive line of people (the Array) approaches the door. The bouncer checks each person against a specific rule: "Are you wearing sneakers?" (the Callback function). If the answer is false, they are turned away. If the answer is true, they are allowed into the club (the New Array).
(3) JavaScript Code Examples
Short Snippet
const numbers = [1, 2, 3, 4, 5, 6];
// The callback must return true or false (or a truthy/falsy value)
const evens = numbers.filter((num) => {
return num % 2 === 0; // true if even, false if odd
});
console.log(evens); // [2, 4, 6]
Fuller Example
const inventory = [
{ name: "Apples", type: "fruit", count: 10 },
{ name: "Carrots", type: "vegetable", count: 5 },
{ name: "Bananas", type: "fruit", count: 0 },
{ name: "Broccoli", type: "vegetable", count: 12 }
];
// Find all items that are fruits AND are in stock
const inStockFruits = inventory.filter(item => item.type === "fruit" && item.count > 0);
console.log(inStockFruits);
// Output: [ { name: "Apples", type: "fruit", count: 10 } ]
4. Common Mistakes & Pitfalls
Mistake 1: Trying to return the value instead of a boolean
The mistake: Writing the callback function as if you are using map(), returning the actual data you want instead of a true/false condition.
Why it's wrong: filter() does not transform data. It only uses your return value to evaluate true or false. If you return a truthy value (like an object or a string), filter() simply says "Ah, they passed the test!" and copies the original item into the new array.
Incorrect:
const words = ["hi", "hello", "hey"];
// Developer wants an array of just the word "hello"
const result = words.filter(word => {
if (word === "hello") {
return word; // This is a string, which is truthy!
}
});
// Since the string "hello" is truthy, it passes.
// The others implicitly return undefined (falsy), so they fail.
// This "happens" to work, but is terrible practice!
Fix:
// Return a boolean expression!
const result = words.filter(word => word === "hello");
Mistake 2: Losing Context Binding (this) in Filter Callbacks
The mistake: Passing methods from Filter instances as standalone callbacks to timers or event listeners without explicitly binding this.
Why it's wrong: Extracting object methods disassociates them from their target parent instance, causing this to resolve to undefined (in strict mode) or window/globalThis at runtime.
Incorrect:
const obj = {
name: "filter",
log() { console.log(this.name); }
};
setTimeout(obj.log, 100); // ❌ Output: undefined (loses object context)
Fix:
const obj = {
name: "filter",
log() { console.log(this.name); }
};
setTimeout(() => obj.log(), 100); // Correct: Arrow function captures lexical context
Mistake 3: Unhandled Asynchronous Failures in Filter Operations
The mistake: Executing asynchronous operations within Filter without wrapping await calls in try...catch blocks or chaining .catch().
Why it's wrong: Unhandled promise rejections trigger UnhandledPromiseRejectionWarning in Node.js or unhandled rejection errors in modern browsers, leaving application state in corrupted or uncoordinated states.
Incorrect:
async function processData() {
const res = await fetch("/api/filter"); // ❌ Unhandled network failure crashes execution flow
const data = await res.json();
return data;
}
Fix:
async function processData() {
try {
const res = await fetch("/api/filter");
if (!res.ok) throw new Error(`HTTP Error: ${res.status}`);
return await res.json();
} catch (err) {
console.error(`Caught error in filter: ${err.message}`);
return null;
}
}
5. Practice Exercises
Exercise 1: Inventory Catalog Price & Stock Filter
Scenario: An e-commerce catalog service filters product items based on minimum stock and max price constraints using filter().
Requirements:
- Write filterProducts(products, maxPrice).
- Filter products where item.inStock is true and item.price ≤ maxPrice.
- Return new filtered array.
Answer
Implementation
function filterProducts(products, maxPrice) {
if (!Array.isArray(products)) return [];
return products.filter(item => item.inStock && item.price <= maxPrice);
}
// Verification tests
const catalog = [
{ name: "Laptop", price: 1000, inStock: true },
{ name: "Mouse", price: 25, inStock: true },
{ name: "Keyboard", price: 75, inStock: false }
];
const affordable = filterProducts(catalog, 50);
console.assert(affordable.length === 1 && affordable[0].name === "Mouse", "Test 1 Failed");
Technical Explanation
- filter() Non-Mutating Creation: Array.prototype.filter(predicate) constructs a brand new array containing elements that pass the predicate test.
- Shallow Reference Retention: Object elements in the filtered array retain reference pointers to original objects.
- Predicate Evaluation: If predicate returns truthy for an element, it is included; if falsy, skipped.
Exercise 2: Security Audit Log Severity Filter
Scenario: A security SIEM system extracts high-severity alert logs from raw log entries using filter().
Requirements:
- Write extractHighSeverityLogs(logEntries).
- Filter log entries where severity === "ERROR" or severity === "CRITICAL".
- Return filtered array.
Answer
Implementation
function extractHighSeverityLogs(logEntries) {
if (!Array.isArray(logEntries)) return [];
return logEntries.filter(log => log.severity === "ERROR" || log.severity === "CRITICAL");
}
// Verification tests
const logs = [
{ id: 1, severity: "INFO" },
{ id: 2, severity: "ERROR" },
{ id: 3, severity: "CRITICAL" }
];
const highSev = extractHighSeverityLogs(logs);
console.assert(highSev.length === 2, "Test 1 Failed");
Technical Explanation
- Subset Extraction: filter() reduces dataset size without altering element structure.
- Empty Result Safety: If no elements match predicate, filter() returns an empty array [] rather than null.
- Predicate Purity: Keep predicate callbacks pure and free of side-effects.
Exercise 3: Active User Subscription Filter
Scenario: A SaaS billing engine extracts active customer subscription records for invoice generation.
Requirements:
- Write getActiveSubscriptions(users).
- Filter users where user.subscriptionStatus === "ACTIVE".
- Return active users.
Answer
Implementation
function getActiveSubscriptions(users) {
if (!Array.isArray(users)) return [];
return users.filter(user => user.subscriptionStatus === "ACTIVE");
}
// Verification tests
const usersList = [
{ id: 1, subscriptionStatus: "ACTIVE" },
{ id: 2, subscriptionStatus: "CANCELLED" }
];
const active = getActiveSubscriptions(usersList);
console.assert(active.length === 1 && active[0].id === 1, "Test 1 Failed");
Technical Explanation
- Declarative Data Processing: filter() replaces verbose for-loops and push statements with declarative logic.
- Array Composition: Filtered results can be chained directly into .map() or .reduce().
- Source Array Immutability: The source array is never modified by filter().
6. Related Terms
- Map — Used when you want to transform data, resulting in an array of the same length.
- find() — Similar to
filter, but stops and returns only the first item that passes the test. - every() — Related concept: every().
- reduce() — Related concept: reduce().
7. Key Takeaways
filter()creates a new array containing only the items that passed a test.- The new array will be smaller than or equal to the original array's length.
- The callback function MUST return a boolean (or a truthy/falsy value).
- It does not mutate the original array.