12 - Как работают методы массива filter и find?

Оценить качество материала и подачу материала автором видео:

Front-end

Трудоустройтесь middle front-end разработчиком на React JS (TypeScript) за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Front-end

Back-end

Трудоустройтесь middle back-end разработчиком за 12-16 месяцев обучения с ежедневной менторской поддержкой в формате видео 1 на 1 и коммерческими проектами в портфолио

Перейти на курс
Back-end

Карьерный бустер

Получите коммерческий опыт на реальных стартапах, прокачайте tech & soft навыки, научитесь работать в команде, проходить собеседования и получите первую работу в IT!

Перейти на курс
Карьерный бустер

Основы Front-end

Сделайте первый шаг в IT, освоив базовые знания разработки и научившись создавать небольшие проекты на JavaScript

Перейти на курс
Основы Front-end

Основы Back-end

Сделайте первый шаг в IT, освоив базовые знания разработки. Без опыта. Без математики. Только практика: JavaScript, SQL, Node JS, база данных

Перейти на курс
Основы Back-end

Методы filter, find и сложность O(n)

Автор конспекта: Стогниева Виктория

📌

Метод filter создаёт новый массив, содержащий только те элементы исходного массива, для которых переданная функция-колбэк возвращает true.

🔗 Ссылка на документацию filter

🔧 Как работает filter

  1. У нас есть массив элементов (барашки, люди, слова, числа).

  2. Мы вызываем у массива метод .filter(callback).

  3. Callback-функция (функция-предикат) получает на вход каждый элемент массива и возвращает true или false.

  4. Все элементы, для которых callback вернул true, складываются в новый массив, который filter возвращает.

Разберем на примере с овечками

🤔 Идея

  • У нас есть массив овечек (объектов).

  • Каждая овечка ➡️ проверяется на условие (например, какой цвет у овечки).

  • Овечки, прошедшие проверку с помощью функции-предикат, попадают в новый массив.

  • Исходный массив овечек остаётся без изменений → создаётся новый массив желтых овечек.

sheeps

⚙️ Реализация

  • Для того чтобы метод filter отфильтровал овечек, мы передаем внутрь него функцию-callback (предикат).
  • Callback работает с каждой овечкой и возвращает true, если овечка подходит под условие (например,она желтого цвета), и false — если нет.
  • После того как каждая овечка проверена, filter отдает нам результирующий массив с подходящими овечками.

Как данная функция выглядела бы в js:

js
const sheeps = [sheep1, sheep2, sheep3, sheep4] // массив, в котором сидят объекты (овечки)
const yellowSheeps = sheeps.filter(
  // передаём в него callback функцию.
  // callback в свою очередь принимает овечку
  (sheep) => {
    return sheep.color === "yellow" // проверяем, какой цвет у овечки, возвращаем результат проверки
  },
)

Именно то, что возвращается из callback функции (true или false), определяет, попадет ли элемент в новый массив. Callback вызывается столько раз, сколько элементов в массиве. И каждый раз в callback приходит другой элемент массива.

Разберем на примере с людьми

🤔 Идея

  • У нас есть массив объектов (люди).

  • Нужно отфильтровать женщин.

  • Используем filter, передаём в него функцию-предикат, которая принимает "человека" и возвращает true, если нашлась женщина.

  • Исходный массив остаётся без изменений → создаётся новый массив объектов.

people

⚙️ Реализация

  • Для того чтобы метод filter отфильтровал людей, мы передаем внутрь него функцию-сallback.
  • Callback работает с каждым человеком, определяет его пол и возвращает true, если пол женский.
  • После того как каждый человек обработан, filter отдает нам результирующий массив с женщинами.

Как данная функция выглядела бы в js:

js
const people = [person1, person2, person3] //массив, в котором сидят объекты(люди)
 
// вызываем у этого исходного массива метод .filter
const women = people.filter((person) => {
  const sex = detectSex(person) // определяем пол человека
  return sex === "female" // возвращаем true для женщин
})

Когда мы используем filter, мы не создаем копии объектов. Мы просто создаем новый массив, в который попадают ссылки на те же объекты, что и в исходном массиве, если они удовлетворяют условию. Это означает, что если мы изменим объект в отфильтрованном массиве, то это изменение отразится и на исходном массиве, потому что это один и тот же объект.

🔧 Как работает find

📌

Метод find возвращает первый элемент массива, который удовлетворяет условию проверочной функции.

🔗 Ссылка на документацию find

Важно отметить, что find возвращает сам элемент, а не массив. Если элемент не найден, возвращается undefined.

Разберем на примере с овечками

🤔 Идея

  • У нас есть массив овечек (объектов).

  • Нужно найти первую овечку желтого цвета.

  • Используем find, передаём в него функцию-предикат, которая проверяет цвет овечки.

  • Возвращается первый подходящий объект или undefined, если ничего не найдено.

sheeps

sheepsUndefined

⚙️ Реализация

js
const sheeps = [sheep1, sheep2, sheep3, sheep4]
const yellowSheeps = sheeps.find((sheep) => {
  return sheep.color === "yellow"
})

Важно: метод find прекращает поиск после первого совпадения. Также, как и в случае с filter, метод find не изменяет исходный массив и возвращает ссылку на тот же объект (если элемент найден).

🔧 Сложность алгоритма O(n)

📌

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

📌

Сложность O(n) означает, что время выполнения алгоритма линейно зависит от количества элементов в массиве.

O(n)

💡

График наглядно демонстрирует, почему сложность O(n) называется линейной — время выполнения растет прямо пропорционально объему обрабатываемых данных. Метод filter имеет сложность O(n).

🧠 Выводы о сложности O(n):

  • Линейный рост: время выполнения увеличивается пропорционально количеству элементов.
  • Предсказуемость: зная время для одного элемента, можно предсказать время для n элементов.
  • Эффективность: алгоритмы с сложностью O(n) считаются эффективными для большинства практических задач.

Разберем на примере людей

⚙️ Реализация

  • Метод filter применяется к массиву persons.
  • Функция-колбэк внутри filter проверяет условие person.age >= 18 для каждого элемента.
  • Сложность O(n) означает, что время выполнения алгоритма линейно зависит от количества элементов в массиве.
  • В данном случае, поскольку мы перебираем каждый элемент массива ровно один раз, сложность составляет O(n), где n - количество элементов в массиве.
  • Для массива из 3 элементов будет выполнено 3 проверки, для массива из 100 элементов - 100 проверок, и так далее. Таким образом, время выполнения растет линейно с ростом размера массива.
js
const persons = [
  { name: "dmitry", age: 37 },
  { name: "john", age: 17 },
  { name: "rita", age: 18 },
]
 
const adults = persons.filter((person) => {
  return person.age >= 18
})
 
console.log(adults)
// Результат: [{name: 'dmitry', age: 37}, {name: 'rita', age: 18}]
🔄

Важное свойство метода filter — он не изменяет (не мутирует) исходный массив, а создает и возвращает новый массив.

js
const persons = [
  { name: "dmitry", age: 37 },
  { name: "john", age: 17 },
  { name: "rita", age: 18 },
]
 
const adults = persons.filter((person, index) => {
  console.log("predicate is called: " + index)
  return index > 1
})
 
console.log(adults)
// Результат: [{name: 'rita', age: 18}]
📌

Метод filter может принимать второй параметр — индекс текущего элемента, который показывает позицию элемента в исходном массиве.

js
const persons = [
  { name: "dmitry", age: 37 },
  { name: "john", age: 17 },
  { name: "rita", age: 18 },
]
 
const adults = persons.filter((person, index, array) => {
  console.log(array) // выведет массив persons три раза (по одному для каждого элемента)
  return index > 1
})
 
console.log(adults) // массив с одним элементом: {name: 'rita', age: 18}
📌

В данном примере в колбэке используется третий параметр - array, который представляет собой исходный массив, над которым производится операция filter.

js
const persons = [
  { name: "dmitry", age: 37 },
  { name: "john", age: 17 },
  { name: "rita", age: 18 },
]
 
const adults = persons.filter(predicate2)
console.log(adults)
 
function predicate(person, index, array) {
  return person.age >= 18
}
 
function predicate2(person, index, array) {
  return person.age < 18
}

⚙️ Реализация с помощью метода find

  • В данном случае функция predicate проверяет, что возраст человека (person.age) больше или равен 18. Таким образом, будет найден первый совершеннолетний человек в массиве.
  • Метод find перебирает элементы до первого совпадения, затем останавливается.
  • После нахождения элемента, он выводится в консоль в формате JSON строки.
js
const persons = [
  { name: "dmitry", age: 37 },
  { name: "john", age: 17 },
  { name: "rita", age: 18 },
]
 
const adult = persons.find(predicate)
console.log("adult: " + JSON.stringify(adult)) // adult: {"name":"dmitry","age":37}
 
function predicate(person, index, array) {
  return person.age >= 18
}
 
function predicate2(person, index, array) {
  return person.age < 18
}

🏠 Домашнее задание

🎯 Цель задания:

Закрепить понимание работы методов filter и find, концепций предиката, callback-функций и асимптотической сложности алгоритмов.

Ключевые понятия:

  • Предикат - функция, возвращающая true или false
  • Callback - функция, передаваемая в другую функцию
  • Иммутабельность - методы не изменяют исходный массив
  • Сложность O(n) - линейная зависимость времени от количества элементов

Задача 1

Работа с массивом чисел

Дан массив чисел:

javascript
const numbers = [1, 15, 3, 42, 8, 19, 7, 25, 11, 33]

Выполни следующие задания:

  1. Фильтрация четных чисел
javascript
// Найди все четные числа
const evenNumbers = XXX // твой код
console.log(evenNumbers)
  1. Фильтрация чисел больше 10
javascript
// Найди числа больше 10
const bigNumbers = XXX // твой код
console.log(bigNumbers)
  1. Поиск первого числа больше 20
javascript
// Найди первое число больше 20
const firstBig = XXX // твой код
console.log(firstBig)

Задача 2

Работа с объектами (основная)

Дан массив студентов:

javascript
const students = [
  { name: "Анна", age: 19, grade: 7, course: 2 },
  { name: "Диана", age: 17, grade: 8, course: 1 },
  { name: "Виктория", age: 21, grade: 5, course: 3 },
  { name: "Григорий", age: 18, grade: 9, course: 2 },
  { name: "Борис", age: 20, grade: 4, course: 3 },
  { name: "Евгений", age: 16, grade: 6, course: 1 },
]

Часть A: Метод filter

  1. Взрослые студенты
javascript
// Найди студентов 18+ лет
const adults = students.filter(/* твой предикат */)
console.log(adults)
  1. Отличники
javascript
// Найди студентов с оценкой 8+
const excellentStudents = XXX // твой код
console.log(excellentStudents)
  1. Студенты второго курса
javascript
// Найди студентов 2 курса
const secondCourse = XXX // твой код
console.log(secondCourse)
  1. Сложная фильтрация
javascript
// Найди взрослых студентов с оценкой выше 6
const adultGoodStudents = XXX // твой код
console.log(adultGoodStudents)

Часть B: Метод find

  1. Поиск по имени
javascript
// Найди студента по имени 'Виктория'
const victoria = XXX // твой код
console.log(victoria)
  1. Первый отличник
javascript
// Найди первого студента с оценкой 8+
const firstExcellent = XXX // твой код
console.log(firstExcellent)
  1. Поиск несуществующего
javascript
// Попытайся найти студента младше 16 лет
const tooYoung = XXX // твой код
console.log(tooYoung) // должно быть undefined

Задача 3

Создание предикатов

Создай отдельные функции-предикаты:

javascript
// 1. Функция для проверки совершеннолетия
function isAdult(person) {
  // твой код
}
 
// 2. Функция для проверки отличника (8+)
function isExcellent(student) {
  // твой код
}
 
// 3. Функция для проверки курса
function isSecondCourse(student) {
  // твой код
}
 
// Используй эти функции с методами filter и find
const adultStudents = students.filter(isAdult)
const firstExcellent = students.find(isExcellent)
const secondCourse = students.filter(isSecondCourse)
const firstSecondCourse = students.find(isSecondCourse)

Задача 4

Работа с индексами

javascript
const colors = ["красный", "синий", "зелёный", "жёлтый", "фиолетовый"]
 
// 1. Найди цвета с четными индексами (0, 2, 4...)
const evenIndexColors = colors.filter(/* используй второй параметр - index */)
 
// 2. Найди первый цвет, индекс которого больше 2
const colorAfterIndex2 = colors.find(/* используй index */)

Задача 5

Анализ сложности (теоретическая)

Ответь на вопросы:

  1. Если в массиве 1000 элементов, сколько раз максимально может выполниться предикат в методе filter?
  2. Сколько раз максимально может выполниться предикат в методе find для того же массива?
  3. В каком случае метод find будет работать быстрее всего?
  4. Почему сложность обоих методов считается O(n)?

💡

Методы filter и find — это инструменты, которые ты будешь использовать каждый день в реальной разработке, от простой фильтрации списков до сложной обработки данных с сервера. Освоив их сейчас, ты заложишь фундамент для профессионального мышления React-инженера! 🚀

Боевой маршрут (React Путь Самурая: без альтернатив)

Видеоурок - 14 видео из 30