Метод filter() используется для фильтрации массива и возврата подмножества исходного массива. Вот как работает метод filter().

Метод filter в JavaScript создает неглубокую копию массива, фильтруя его на основе ряда условий. Он принимает функцию обратного вызова. Массив, который производит filter, обычно будет уменьшенной версией исходного массива. Вот простой пример:

let myArray = [ '⚡️', '🔎', '🔑', '🔩' ];
let filteredArray = myArray.filter((element) => {
    return (element == '🔑' || element == '🔩'))
});
console.log(filteredArray); // [ '🔑', '🔩' ]

Как видите, метод filter позволяет элементу находиться в новом отфильтрованном массиве, если этот элемент возвращает true. Он эффективно перебирает каждый элемент и запускает для него тест, чтобы увидеть, что должно остаться. Поскольку стрелочные функции неявно возвращают значение true в одной строке, вы можете увидеть более сокращенную версию этого кода, написанную следующим образом:

let myArray = [ '⚡️', '🔎', '🔑', '🔩' ];
let filteredArray = myArray.filter(element => element == '🔑' || element == '🔩');
console.log(filteredArray); // [ '🔑', '🔩' ]

Функция обратного вызова метода фильтра

Как уже упоминалось, filter принимает функцию обратного вызова. Функция обратного вызова состоит из 3 аргументов:

Array.filter((element, index, array) => {
    // Filter the array
});

Давайте посмотрим, что делает каждый из них.

элемент

Это текущий элемент, который проверяет filter. filter просматривает каждый элемент в массиве, чтобы проверить, должен ли он существовать в новом отфильтрованном массиве.

индекс

Это нулевой индекс элемента массива, с которым мы работаем. Например, если бы мы просматривали первый элемент в массиве, это было бы 0.

множество

Это весь массив, если вы хотите что-то сделать с исходным массивом.

Мутирование массивов в методе фильтра

Поскольку фильтр использует функцию обратного вызова, можно изменить исходный массив, который мы исследуем. Например, мы могли бы помещать новые элементы в массив каждый раз, когда мы фильтруем элемент:

let myArray = [ '⚡️', '🔎', '🔑', '🔩' ];
let filteredArray = myArray.filter((element) => {
    myArray.push('⚡️');
    return true;
});
console.log(filteredArray); // [ '⚡️', '🔎', '🔑', '🔩' ]

Как вы, возможно, уже поняли, это приведет к бесконечному циклу. К счастью, как и в случае с reduce, Javascript не позволяет этого делать — вместо этого любые новые элементы в массиве, добавляемые таким образом, игнорируются. Однако мутация существующих элементов вполне допустима:

let myArray = [ '⚡️', '🔎', '🔑', '🔩' ];
let filteredArray = myArray.filter((element, index) => {
    myArray[index + 1] = '⚡️';
    return (element == '⚡️');
});
console.log(filteredArray); // [ '⚡️', '⚡️', '⚡️', '⚡️' ]

Фильтрация массивов объектов

Фильтрация массивов объектов следует тем же соглашениям, что и для массивов. Мы можем фильтровать дочерние свойства объектов в массиве, используя нотацию .. Например, если бы я хотел отфильтровать следующий массив по age, где возраст должен быть >18, я бы сделал что-то вроде этого:

let myArray = [ { age: 4 }, { age: 12 }, { age: 19 }, { age: 21 } ];
let filteredArray = myArray.filter((element, index) => {
    return (element.age > 18);
});
console.log(filteredArray); // [ { age: 19 }, { age: 21 } ]

Фильтрация массивов по критериям поиска

Обычно filter используется для получения массива значений и поиска в них на основе поискового запроса. Это можно сделать с помощью includes или regex. Например:

let myArray = [ 'cat', 'catdog', 'dog', 'fish', 'fishcat' ]
let filteredArray = myArray.filter((element, index) => {
    return element.match(/cat/)
});
console.log(filteredArray); // ['cat', 'catdog', 'fishcat']

Фильтр делает поверхностную копию массивов

Хотя может показаться, что filter создает новую копию исходного массива, это не так. На самом деле filter создает мелкую копию исходного массива, а это означает, что если мы изменим объекты внутри массива, оригинал тоже изменится. Чтобы понять это, давайте снова посмотрим на наш пример с возрастом:

let myArray = [ { age: 4 }, { age: 12 }, { age: 19 }, { age: 21 } ];
let filteredArray = myArray.filter((element, index) => {
    return (element.age > 18);
});
console.log(filteredArray); // [ { age: 19 }, { age: 21 } ]
filteredArray[0].age = 50;
filteredArray[1] = { age: 40 };
console.log(filteredArray); // [ { age: 50 }, { age: 40 } ]
console.log(myArray); // [ { age: 4 }, { age: 12 }, { age: 50 }, { age: 21 } ]

Как видите, изменение отфильтрованного массива с использованием нотации filteredArray[0].age также изменяет исходный, но подождите! filteredArray[1] = { age: 40 } изменяет только отфильтрованный массив. Это связано с тем, что, хотя Javascript интерпретирует нотацию . как обновление обоих массивов, он интерпретирует нотацию [] в квадратных скобках как установку нового значения во второй позиции отфильтрованного массива.

Это просто еще одна особенность Javascript, которая может сбивать с толку, но ее очень полезно знать!

Заключение

Метод фильтрации широко используется и является простым способом изменения и создания новых подмножеств массивов на основе определенных критериев. Следует отметить, что из исходного массива создается только неглубокая копия, поэтому изменение массива определенным образом повлияет на оригинал.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord. Заинтересованы в Взлом роста? Ознакомьтесь с разделом Схема.