Какими способами можно отфильтровать массив в JS (JavaScript)

Как отфильтровать массив в JS (JavaScript)

16.02.2024
265
13 мин.
0

В этой статье рассматриваются различные способы, как отфильтровать массив в JS (JavaScript) с использованием нескольких условий. Для начала давайте взглянем на метод filter и как его можно использовать для этой цели.

Затем мы изучим разные способы фильтрации массива путём проверки на соответствие нескольким условиям, в том числе:

  1. С помощью логического оператора &&.
  2. Использование дополнительной фильтрации с помощью оператора ||.
  3. Фильтрация массива объектов.
  4. Объединение обоих && и || для фильтрации массива.
  5. Использование оператора if и цикла for для задания нескольких условий.
  6. Использование метода every для фильтрации массива.

Метод filter

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

Условие фильтрации как таковое не изменяет исходный массив. Оно просто создаёт копию извлечённых значений. Например:

const nums = [11,51,4,30,60];
 
let result = nums.filter((num) => {
  return num <= 30;
});
 
console.log(result); // [11, 4, 30]

Как вы можете видеть, у нас есть массив со случайными числами в диапазоне от 1 до 60. Например, мы хотим извлечь только числа, которые меньше 30?

Для этого мы будем использовать метод filter для массива nums:

  1. Он выполняет итерацию по всему массиву.
  2. Сохраняет текущее значение массива во временной переменной для каждой итерации. Для нашего примера мы назвали переменную num. Вы можете назвать её как угодно.
  3. Также он проверяет данное условие для каждой итерации. В нашем примере мы следим за тем, является ли текущее значение в num меньше или равно 30. Если это так, мы возвращаем его. В противном случае итерация будет пропущена.
  4. Возвращает новый массив с отфильтрованными значениями после завершения всех итераций. В нашем примере кода мы сохранили этот массив в новой переменной result.

Как вы можете видеть, пока что мы проверяем только одно условие для каждой итерации. Это выглядит не очень реалистичным для практического применения в программировании. Как правило, чаще всего на практике используется более одного условия или требуется выполнить какие-либо сложные вычисления. А полученный результат будет затем использовать для фильтрации.

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

Отфильтровать массив в JS через логический оператор && и несколько условий

Один из самых простых способов добавить несколько условий в метод filter — это использовать логический оператор &&. Этот оператор ссылается на условие ||, где оба условия, использующие этот оператор в качестве соединения, должны быть истинными, чтобы весь оператор был истинным.

Давайте рассмотрим это подробнее:

(a >= 5) && (a <= 10)

Как вы можете видеть, здесь мы имеем дело с двумя условиями: «а» должно быть больше или равно 5 и меньше или равно 10.

Допустим, значение «a» равно 7. Если применить это значение к приведённому выше утверждению, то результатом будет true. Это объясняется тем, что 7 больше 5, но меньше 10.

С другой стороны, 3, 30 или любое другое число, отличное от 5 до 10, выдаст false. Так работает условие ||. Оба условия должны быть истинными, чтобы всё утверждение было истинным. Итак, если вы хотите, чтобы при фильтрации выполнялось несколько условий, вы можете использовать этот оператор. Давайте применим два условия к фрагменту кода, который мы рассматривали ранее:

const nums = [11,51,4,30,60];
 
let result = nums.filter((num) => {
  return num >= 10 && num <= 30;
});
 
console.log(result); // [11, 30]

Как вы можете видеть, мы добавили второе условие, согласно которому число должно быть больше или равно 10. Теперь результирующий отфильтрованный массив будет содержать только два числа (11 и 30) вместо исходных трёх.

Добавление более двух условий

Конечно, можно добавить более двух условий, используя оператор &&. Результат будет тот же.

Если у вас есть три отдельных условия, соединённых двумя операторами &&, то все они должны быть true, чтобы весь оператор возвращал true. Даже если одно из условий возвращает false, но остальные два являются true, весь оператор вернёт false.

Теперь давайте попробуем применить три условия к этому же фрагменту кода:

let result = nums.filter((num) => {
  return num >= 10 && num <= 30 && num != 11;
});
 
console.log(result); // [30]

Мы добавили новое условие, которое проверяет, не равно ли число 11. Таким образом, любое число от 10 до 30 (включая как 10, так и 30), если оно не равно 11, будет отфильтровано и помещено в новый массив. Следовательно, отфильтрованный массив теперь имеет только один результат (30), потому что это единственное значение, которое соответствует всем трём условиям.

Аналогичным образом вы можете добавить в код фильтрации столько условий, сколько необходимо. Ключевым требованием является то, что они должны соединяться оператором &&.

Необязательная фильтрация через логический оператор OR

Оператор || отлично подходит, если необходимо получить все указанные условия истинными. Но что делать, если нужно проверить несколько условий, но вам все равно, все ли они истинны. Если вас устраивает, что какое-либо из условий возвращает true, то вам лучше использовать оператор ||. Если какое-либо из условий, использующих оператор ||, возвращает true, весь оператор вернёт true.

Этот код вернёт false только в том случае, если все условия вернут false. Вспомним условный оператор, который мы рассматривали ранее. Давайте изменим его с помощью оператора ||.

(a >= 5) || (a <= 10)

В приведённом выше утверждении, если число больше или равно 5, или меньше или равно 10, мы получим значение true.

В чём же проблема с этим утверждением? Учитывая то, как все было настроено, каждое отдельное число, даже отрицательное, пройдёт этот тест. Это объясняется тем, что каждое число будет либо меньше 5, либо больше 10. Но сама идея заключается в том, если выполнение только одного из условий является достаточным, то можно использовать оператор ||.

Теперь давайте применим этот оператор к массиву, с которым мы работали. Изменённый фрагмент кода будет выглядеть так:

const nums = [11,51,4,30,60];
 
let result = nums.filter((num) => {
  return num >= 50 || num == 4;
});
 
console.log(result); // [51, 4, 60]

Как вы можете видеть, мы изменили условие таким образом, чтобы любое значение, которое больше или равно 50 или равно числу 4 будет отфильтровано. Результатом станут числа 51, 60 и 4.

Точно так же, как и в случае с оператором ||, вы можете применить более одного этого оператора по отношению к текущему утверждению. Это позволит получить комбинированный результат. Независимо от того, сколько операторов || используется, даже если один из них имеет значение true, все утверждение будет истинным. Даже если остальные условия ложны.

Отфильтровать массив объектов в JS с несколькими условиями

Какими способами можно отфильтровать массив в JS (JavaScript)
Для фильтрации массива в JavaScript могут применяться различные способы (изображение создано с помощью ИИ)

Для фильтрации массива объектов можно применить и несколько условий. В качестве примера создадим массив people, элементами которого являются объекты. Каждый из них будет иметь одинаковые свойства (имя, возраст, средний балл).

const people = [
  {
    name: 'John',
    age: 15,
    gpa: 8
  },
  {
    name: 'Amber',
    age: 16,
    gpa: 9
  },
  {
    name: 'Raj',
    age: 15,
    gpa: 8.5
  },
  {
    name: 'Susan',
    age: 16,
    gpa: 7.8
  }
]

Теперь давайте применим метод filter к этому массиву. Для каждой итерации он будет обращаться к одному из объектов, который будет храниться во временной переменной person. Мы также будем проверять, равен ли person.age 15, а person.gpa больше или равен 8. Если это так, то код вернёт этот объект.

Результатом станет отбор первого и третьего объектов. Они единственные со свойством «возраст» равным 15 лет и средний балл которых превышает 8.

let result = people.filter((person) => {
  return person.age == 15 && person.gpa >= 8;
});
 
console.log(result); // [{name: 'John', age: 15, gpa: 8},{name: 'Raj', age: 15, gpa: 8.5}]

С другой стороны, если вы используете оператор || в этих двух условиях, то результатом станут первые три объекта. В этом случае это связано с тем, что «возраст» теперь может быть либо 15 лет, либо средний балл больше 8.

let result = people.filter((person) => {
  return person.age == 15 || person.gpa >= 8;
});
 
console.log(result); // [{name: 'John', age: 15, gpa: 8},{name: 'Amber', age: 16, gpa: 9},{name: 'Raj', age: 15, gpa: 8.5}]

В целом, можно поэкспериментировать с этими условиями, чтобы получить различные результаты фильтрации массива.

Сложные условия с операторами AND, OR и NOT

Отфильтровать массив в JS можно с использованием сложных условий с помощью сочетания операторов AND, OR и NOT. Давайте рассмотрим ещё один пример. Мы будем использовать тот же массив объектов, который мы применяли в предыдущем разделе. Тем не менее, мы немного изменим условия следующим образом. Возраст пользователя 15 ИЛИ 16 лет, но его зовут Сьюзан. При выполнении этих условий мы должны получить данные Джона, Раджа и Сьюзан.

let result = people.filter((person) => {
  return person.age == 15 || (person.age === 16 && person.name == 
    'Susan');
});
 
console.log(result); // [{name: 'John', age: 15, gpa: 8},{name: 'Raj', age: 15, gpa: 8.5},{name: 'Susan', age: 16, gpa: 7.8}]

Как вы можете видеть выше, наше утверждение состоит из двух частей. Условие && заключено в круглые скобки. Почему? Потому, что мы хотим, чтобы два условия по обе стороны от && оценивались вместе, но отдельно от остальной части условия.

Таким образом, сравнение будет осуществляться слева направо. Код сначала проверит, равно ли свойство age 15. Если это так, то по умолчанию весь оператор вернёт значение true (из-за промежуточного условия ||). Если age не равен 15, код перейдёт к следующей части условия, которая проверит, равен ли он 16 и зовут ли человека Сьюзен. При получении true, всё утверждение снова будет истинным.

В случае, когда оба условия по обе стороны от || окажутся ложными (возраст не 15 и имя не Сьюзан), то все утверждение вернёт false. Таким образом, можно объединять и сопоставлять условия, чтобы получить разные результаты.

Использование операторов if и else для задания нескольких условий

Вы также можете использовать операторы if и else, чтобы задать несколько условий для фильтрации массива или совокупности объектов.

Посмотрите на фрагмент кода ниже:

let result = people.filter((person) => {
  if(person.age === 15) {
    return true;
  }
  else if(person.age === 16) {
    if(person.name === 'Susan') {
      return true;
    }
  }
  else {
    return false;
  }
});
 
console.log(result); // [{name: 'John', age: 15, gpa: 8},{name: 'Raj', age: 15, gpa: 8.5},{name: 'Susan', age: 16, gpa: 7.8}]

Как вы можете видеть, мы проверяем наличие трёх различных условий (где одно из этих условий вложено в другое), используя операторы if, else if и else.

Мы возвращаем значение true (и, в свою очередь, элемент массива, относящийся к текущей итерации), если:

  1. Возраст человека — 15 лет.
  2. Или если человеку 16 лет и его зовут Сьюзан.
  3. В противном случае мы получаем значение false.

Помните, как мы использовали это условие в предыдущем фрагменте кода, в котором присутствовали оба оператора AND и OR? Мы просто напишем то же самое условие, используя оператор if else.

Читайте также: Как удалить одинаковые элементы в массиве JavaScript.

Отфильтровать массив в JS методом every

Вы также можете использовать метод every для фильтрации массива при проверке на наличие нескольких условий. Для этого мы немного изменим массив people. Мы удалим свойство age в данных Джона и добавим вместо него свойство sport. Для данных Сьюзан мы просто добавим свойство sport. Свойства остальных объектов останутся прежними.

const people = [
  {
    name: 'John',
    gpa: 8,
    sports: 'Football'
  },
  {
    name: 'Amber',
    age: 16,
    gpa: 9
  },
  {
    name: 'Raj',
    age: 15,
    gpa: 8.5
  },    
  {
    name: 'Susan',
    age: 16,
    gpa: 7.8,
    sports: 'Tennis'
  }
];

Теперь давайте отфильтруем этот массив, выполнив следующие действия:

  1. Создадим новый массив keys со значениями age и sport. Это касается некоторых свойств объектов массива people.
  2. Отфильтруем массив people. Для каждой итерации мы применим метод every к массиву keys. Это будет повторяться через весь массив keys внутри текущей итерации массива people.
  3. Во время итерации проведём проверку, не являются ли оба значения person[key], которые представляют собой свойства person[age] и person[sports] undefined. Таким способом можно определить содержит ли текущий объект оба эти свойства.
  4. Если это так, то код вернёт этот объект. В противном случае ничего не произойдёт.
let keys = ['age','sports'];
 
let result = people.filter((person) => {
  return keys.every(key => person[key] != undefined && person[key] != undefined);
});
 
console.log(result); // [{name: 'Susan', age: 16, gpa: 7.8, sports: 'Tennis'}]

Учитывая, что только данные Сьюзен содержат информацию как о возрасте, так и о видах спорта, то мы получим только её данные.

Кроссбраузерность

Методы filter()some() и every() имеют полную поддержку браузерами.