filter()
The filter()
method creates a new array containing all elements from the original array that pass a test. This test is set using a provided function. The original array is not modified, and returns only the elements that satisfy the condition.
Syntax
const newArray = array.filter(function(currentValue, index, array) {
// return true to add the element to new array, otherwise false
});
Parameters:
- function: Function that tests each element of the array, taking three possible arguments:
- currentValue: The current element being processed.
- index (optional): The index of the current element.
- array (optional): The original array
filter()
was called upon.
Basic usage
Let's look at a simple filtering example using a pizza toppings array:
const pizzaToppings = ['Cheese', 'Pepperoni', 'Mushrooms', 'Olives', 'Anchovies', 'Pineapple'];
// Filter out controversial toppings
const traditionalToppings = pizzaToppings.filter(topping => {
return topping !== 'Anchovies' && topping !== 'Pineapple';
});
console.log(traditionalToppings);
// Output: ['Cheese', 'Pepperoni', 'Mushrooms', 'Olives']
Here's an example filtering toppings based on their length:
const pizzaToppings = ['Cheese', 'Pepperoni', 'Mushrooms', 'Olives', 'Anchovies', 'Pineapple'];
// Filter toppings with names longer than 6 characters
const longNameToppings = pizzaToppings.filter(topping => {
return topping.length > 6;
});
console.log(longNameToppings);
// Output: ['Pepperoni', 'Mushrooms', 'Anchovies', 'Pineapple']
Using the index parameter
The second parameter gives you access to the current index:
const pizzaToppings = ['Cheese', 'Pepperoni', 'Mushrooms', 'Olives', 'Anchovies', 'Pineapple'];
// Filter toppings at even index positions
const evenIndexToppings = pizzaToppings.filter((topping, index) => {
return index % 2 === 0;
});
console.log(evenIndexToppings);
// Output: ['Cheese', 'Mushrooms', 'Anchovies']
The following example will remove any duplicate values:
const pizzaToppings = ['Cheese', 'Pepperoni', 'Cheese', 'Mushrooms', 'Olives', 'Anchovies', 'Pineapple'];
// Filter toppings to keep only the first occurrence of each
const uniqueToppings = pizzaToppings.filter((topping, index, array) => {
return array.indexOf(topping) === index;
});
console.log(uniqueToppings);
// Output: ["Cheese","Pepperoni","Mushrooms","Olives","Anchovies","Pineapple"]
// (This keeps the first occurrence of each topping and removes duplicates)
The function can also be extracted from the filter
method, making it more readable and re-usable:
const pizzaToppings = ['Cheese', 'Pepperoni', 'Mushrooms', 'Olives', 'Anchovies', 'Pineapple'];
const isVegetarian = (topping) => {
const meatToppings = ['Pepperoni', 'Anchovies', 'Bacon', 'Sausage'];
return !meatToppings.includes(topping);
}
const vegetarianToppings = pizzaToppings.filter(isVegetarian);
console.log(vegetarianToppings);
// Output: ['Cheese', 'Mushrooms', 'Olives', 'Pineapple']
Using the array parameter
The third parameter provides reference to the original array:
const pizzaOrders = [
{ type: "Margherita", price: 8 },
{ type: "BBQ Chicken", price: 15 },
{ type: "Veggie", price: 9 },
];
// Function to filter orders that cost more than 10
const expensiveOrders = pizzaOrders.filter((order, index, originalArray) => {
console.log(`Checking order: ${order.type}`);
console.log(`Index: ${index}`);
console.log(`Original Array:`, originalArray);
// Return only orders where price is greater than 10
return order.price > 10;
});
console.log("Original Orders:", pizzaOrders);
console.log("Expensive Orders:", expensiveOrders);
Working with objects in arrays
The filter()
method is useful when working with arrays of objects. The following exmaple will filter all vegetarian pizzas from the objects:
const pizzaMenu = [
{ name: 'Margherita', price: 10, isVegetarian: true },
{ name: 'Pepperoni', price: 12, isVegetarian: false },
{ name: 'Vegetarian', price: 13, isVegetarian: true },
{ name: 'Supreme', price: 15, isVegetarian: false },
{ name: 'Hawaiian', price: 12, isVegetarian: false }
];
// Find all vegetarian pizzas
const vegetarianPizzas = pizzaMenu.filter(pizza => pizza.isVegetarian);
console.log(vegetarianPizzas);
/* Output:
[
{ name: 'Margherita', price: 10, isVegetarian: true },
{ name: 'Vegetarian', price: 13, isVegetarian: true }
]
*/
This example will find pizzas under $13:
const pizzaMenu = [
{ name: 'Margherita', price: 10, isVegetarian: true },
{ name: 'Pepperoni', price: 12, isVegetarian: false },
{ name: 'Vegetarian', price: 13, isVegetarian: true },
{ name: 'Supreme', price: 15, isVegetarian: false },
{ name: 'Hawaiian', price: 12, isVegetarian: false }
];
// Find affordable pizzas (less than $13)
const affordablePizzas = pizzaMenu.filter(pizza => pizza.price < 13);
console.log(affordablePizzas);
/* Output:
[
{ name: 'Margherita', price: 10, isVegetarian: true },
{ name: 'Pepperoni', price: 12, isVegetarian: false },
{ name: 'Hawaiian', price: 12, isVegetarian: false }
]
*/
Chaining filter() with other array methods
A useful feature of filter()
is the ability to chain it with other array methods:
const pizzaMenu = [
{ name: 'Margherita', price: 10, isVegetarian: true },
{ name: 'Pepperoni', price: 12, isVegetarian: false },
{ name: 'Vegetarian', price: 13, isVegetarian: true },
{ name: 'Supreme', price: 15, isVegetarian: false },
{ name: 'Hawaiian', price: 12, isVegetarian: false }
];
// Find names of vegetarian pizzas that cost less than $13
const affordableVegetarianPizzaNames = pizzaMenu
.filter(pizza => pizza.isVegetarian && pizza.price < 13)
.map(pizza => pizza.name);
console.log(affordableVegetarianPizzaNames);
// Output: ['Margherita']
Filtering nested arrays
You can use filter()
with nested arrays and combine it with other methods:
const pizzaStores = [
{
name: "Store 1",
pizzas: [
{ name: "Margherita", price: 10, isVegetarian: true },
{ name: "Pepperoni", price: 12, isVegetarian: false },
{ name: "Supreme", price: 15, isVegetarian: false }
]
},
{
name: "Store 2",
pizzas: [
{ name: "Margherita", price: 11, isVegetarian: true },
{ name: "Vegetarian", price: 13, isVegetarian: true },
{ name: "Hawaiian", price: 12, isVegetarian: false }
]
}
];
// Find stores that offer vegetarian options
const storesWithVegetarianOptions = pizzaStores.filter(store => {
return store.pizzas.some(pizza => pizza.isVegetarian);
});
console.log(storesWithVegetarianOptions.map(store => store.name));
// Output: ["Store 1", "Store 2"]
// Find stores that offer ONLY vegetarian pizzas
const vegetarianOnlyStores = pizzaStores.filter(store => {
return store.pizzas.every(pizza => pizza.isVegetarian);
});
console.log(vegetarianOnlyStores.map(store => store.name));
// Output: [] (no stores offer only vegetarian pizzas)
Practical example: order filtering
const pizzaOrder = [
{ name: 'Margherita', price: 10, quantity: 2, isReady: true },
{ name: 'Pepperoni', price: 12, quantity: 1, isReady: false },
{ name: 'Supreme', price: 15, quantity: 1, isReady: true },
{ name: 'Vegetarian', price: 13, quantity: 3, isReady: false }
];
// Find ready items to be delivered
const readyItems = pizzaOrder.filter(item => item.isReady);
console.log("Ready for delivery:", readyItems.map(item => `${item.quantity}x ${item.name}`));
// Output: Ready for delivery: ["2x Margherita", "1x Supreme"]
// Find items still being prepared
const pendingItems = pizzaOrder.filter(item => !item.isReady);
console.log("Still preparing:", pendingItems.map(item => `${item.quantity}x ${item.name}`));
// Output: Still preparing: ["1x Pepperoni", "3x Vegetarian"]
// Calculate total of ready items
const totalReadyValue = readyItems.reduce((total, item) => total + (item.price * item.quantity), 0);
console.log(`Value of ready items: $${totalReadyValue}`);
// Output: Value of ready items: $35
When to use filter() vs. other methods
Use filter()
when:
- You want to exclude certain elements based on a criteria in the provided function.
- You need to extract elements from the original array based on a condition.
- You need a subset of the original array elements.
Consider using other methods when:
- You need to transform each element (use
map()
). - You need to perform an action without creating a new array (use
forEach()
). - You need to accumulate a value (use
reduce()
). - You need to find just the first matching element (use
find()
). - You need to check if any/all elements match a condition (use
some()
orevery()
).
Conclusion
The filter()
method is ideal for extracting elements from arrays based on conditions. By returning a new array with only the elements that pass a test, filter()
enables you to create subsets of data without modifying the original array. It can also be combined with other array methods, providing a flexible way to work with arrays in JavaScript.