Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает Array.filter() в JavaScript
Array.filter() — одна из самых полезных функций для работы с массивами. Она создает новый массив, содержащий только элементы, которые соответствуют определенному условию. Важно понимать, как она работает на уровне, чтобы написать эффективный код.
Базовая синтаксис и механика
Filter принимает callback-функцию, которая вызывается для каждого элемента массива. Если функция вернула true, элемент включается в новый массив.
const numbers = [1, 2, 3, 4, 5];
// Базовый пример
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// Со всеми параметрами
const result = numbers.filter((element, index, array) => {
console.log(`element: ${element}, index: ${index}, array: ${array}`);
return element > 2;
});
// element: 1, index: 0, array: 1,2,3,4,5
// element: 2, index: 1, array: 1,2,3,4,5
// element: 3, index: 2, array: 1,2,3,4,5
// ...
console.log(result); // [3, 4, 5]
Важные свойства filter()
1. Не изменяет исходный массив (immutable)
const original = [1, 2, 3, 4, 5];
const filtered = original.filter(n => n > 2);
console.log(original); // [1, 2, 3, 4, 5] — не изменился
console.log(filtered); // [3, 4, 5] — новый массив
2. Пропускает пустые элементы в sparse array
const sparse = [1, , 3, , 5];
const result = sparse.filter(x => x > 1);
// Пустые элементы пропускаются
console.log(result); // [3, 5] — индексы 1 и 3 пропущены
3. Порядок сохраняется, но индексы меняются
const arr = ['a', 'b', 'c'];
arr.forEach((_, i) => console.log(i)); // 0, 1, 2
const filtered = arr.filter(x => x !== 'b');
filtered.forEach((_, i) => console.log(i)); // 0, 1 — индекс 'c' стал 1
Примеры с разными типами данных
Фильтрация объектов
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 17 },
{ id: 3, name: 'Charlie', age: 30 }
];
const adults = users.filter(user => user.age >= 18);
console.log(adults);
// [
// { id: 1, name: 'Alice', age: 25 },
// { id: 3, name: 'Charlie', age: 30 }
// ]
Фильтрация строк
const words = ['apple', 'banana', 'apricot', 'cherry'];
// Слова, начинающиеся на 'a'
const startsWithA = words.filter(word => word.startsWith('a'));
console.log(startsWithA); // ['apple', 'apricot']
// Слова длиной > 5 символов
const longWords = words.filter(word => word.length > 5);
console.log(longWords); // ['banana', 'apricot', 'cherry']
Удаление дубликатов с filter
const numbers = [1, 2, 2, 3, 3, 3, 4];
const unique = numbers.filter((num, index, arr) => {
return arr.indexOf(num) === index;
});
console.log(unique); // [1, 2, 3, 4]
// indexOf возвращает первый индекс, поэтому дубликаты фильтруются
Производительность и оптимизация
Проблема: filter() создает новый массив
// Неэффективно: создаём промежуточный массив
const result = data
.filter(x => x > 10)
.map(x => x * 2)
.filter(x => x < 100);
// Эффективнее: одна итерация с reduce
const result = data.reduce((acc, x) => {
if (x > 10) {
const doubled = x * 2;
if (doubled < 100) {
acc.push(doubled);
}
}
return acc;
}, []);
Для больших массивов рассмотри for loop
// for loop быстрее для очень больших массивов
const filtered = [];
for (let i = 0; i < array.length; i++) {
if (condition(array[i])) {
filtered.push(array[i]);
}
}
Пример: фильтрация в React компоненте
function UserList({ users, filterRole }) {
// Фильтруем пользователей при каждом рендере
const filteredUsers = users.filter(user => user.role === filterRole);
return (
<ul>
{filteredUsers.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
// Оптимизированная версия с useMemo
function OptimizedUserList({ users, filterRole }) {
const filteredUsers = useMemo(
() => users.filter(user => user.role === filterRole),
[users, filterRole]
);
return (
<ul>
{filteredUsers.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Цепочка filter и map
const products = [
{ id: 1, name: 'Laptop', price: 1000, inStock: true },
{ id: 2, name: 'Mouse', price: 25, inStock: false },
{ id: 3, name: 'Keyboard', price: 80, inStock: true }
];
// Цепочка: фильтруем по наличию, затем трансформируем
const available = products
.filter(product => product.inStock)
.map(product => ({
...product,
discountedPrice: product.price * 0.9
}));
console.log(available);
// [
// { id: 1, name: 'Laptop', price: 1000, inStock: true, discountedPrice: 900 },
// { id: 3, name: 'Keyboard', price: 80, inStock: true, discountedPrice: 72 }
// ]
Мой подход к использованию filter()
- Используй для фильтрации данных — это читаемо и декларативно
- Комбинируй с map() и reduce() для сложных трансформаций
- Кэшируй результат фильтрации в React с useMemo, если список большой
- Для очень больших данных рассмотри оптимизацию (индексирование, виртуализация)
- Не делай сложную логику в filter() — выноси в отдельные функции для читаемости
Filter — это идеальный инструмент для работы с массивами в функциональном стиле. Но помни о производительности при работе с большими наборами данных.