$ sudo teach IT
РАЗДЕЛ 7 · УРОК 3

filter, find, some, every: ищем и проверяем

Эти четыре метода решают задачи поиска и проверки в массивах. Каждый колбэк должен возвращать true или false — именно это определяет, что попадёт в результат. Разберём когда и что использовать.

⏱ ~25 минут 🎓 Для новичков 📦 JavaScript

🔽 filter: оставь только нужное

filter — это сито. Вы передаёте ему колбэк-предикат (функцию, которая возвращает true или false). Для каждого элемента массива вызывается этот предикат: если он вернул true — элемент попадает в новый массив, если false — отбрасывается.

Слово «предикат» — это просто функция, которая отвечает «да» (true) или «нет» (false). Например: «этот элемент чётный?», «этот пользователь взрослый?».

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Оставить только чётные числа
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // → [2, 4, 6, 8, 10]

// Оставить только нечётные
const odds = numbers.filter(n => n % 2 !== 0);
console.log(odds); // → [1, 3, 5, 7, 9]

// Оставить только числа больше 5
const bigOnes = numbers.filter(n => n > 5);
console.log(bigOnes); // → [6, 7, 8, 9, 10]

// Исходный массив НЕ изменяется
console.log(numbers); // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Теперь с массивом объектов — это типичная задача в реальном коде (фильтр товаров по цене, фильтр пользователей по статусу, и т.д.):

const products = [
  { name: "Ноутбук", price: 80000, inStock: true },
  { name: "Мышь", price: 1500, inStock: false },
  { name: "Монитор", price: 35000, inStock: true },
  { name: "Клавиатура", price: 3000, inStock: true },
  { name: "Наушники", price: 8000, inStock: false }
];

// Только товары в наличии
const available = products.filter(p => p.inStock);
console.log(available.map(p => p.name));
// → ["Ноутбук", "Монитор", "Клавиатура"]

// Товары дешевле 10000 руб.
const cheap = products.filter(p => p.price < 10000);
console.log(cheap.map(p => p.name));
// → ["Мышь", "Клавиатура", "Наушники"]

// Товары в наличии И дешевле 10000
const goodDeal = products.filter(p => p.inStock && p.price < 10000);
console.log(goodDeal.map(p => p.name));
// → ["Клавиатура"]

💡 Важно: если ни один элемент не прошёл проверку, filter вернёт пустой массив [], а не undefined. Это удобно — всегда можно безопасно работать с результатом.

🔍 find: найди первого подходящего

find работает похоже на filter, но возвращает не массив, а один элемент — первый, для которого колбэк вернул true. Если не нашёл — возвращает undefined.

Это как искать нужную книгу на полке: как только нашёл — берёшь и уходишь. Не продолжаешь смотреть дальше.

const users = [
  { id: 1, name: "Алиса", role: "admin" },
  { id: 2, name: "Боб", role: "user" },
  { id: 3, name: "Карл", role: "user" },
  { id: 4, name: "Диана", role: "admin" }
];

// Найти пользователя с id = 3
const user = users.find(u => u.id === 3);
console.log(user); // → { id: 3, name: "Карл", role: "user" }

// Найти первого администратора
const firstAdmin = users.find(u => u.role === "admin");
console.log(firstAdmin); // → { id: 1, name: "Алиса", role: "admin" }
// Только ПЕРВЫЙ — Диана не попала, хотя тоже admin

// Если не нашёл — undefined
const notExist = users.find(u => u.id === 99);
console.log(notExist); // → undefined

⚠️ find возвращает undefined при неудаче! Перед использованием результата всегда проверяйте, что он не undefined: if (user) { ... }. Иначе можно словить ошибку при обращении к свойству несуществующего объекта.

filter vs find: если нужны все подходящие — filter. Если нужен только один (первый) — find. Если нужны все администраторы — filter. Если нужен пользователь по конкретному id — find.

🤔 some: хоть кто-то подходит?

some отвечает на вопрос: «Есть ли в массиве хотя бы ОДИН элемент, для которого условие истинно?». Он возвращает true или false.

some прекращает проверку сразу, как только найдёт первый подходящий элемент — это делает его эффективным. Если нашёл — сразу возвращает true, не смотрит дальше.

const ages = [15, 22, 17, 30, 14];

// Есть ли хоть один совершеннолетний?
const hasAdult = ages.some(age => age >= 18);
console.log(hasAdult); // → true (22 и 30 подходят)

// Есть ли хоть один ребёнок до 10 лет?
const hasChild = ages.some(age => age < 10);
console.log(hasChild); // → false (никто не подходит)

// Практический пример: проверить наличие товара в корзине
const cart = [
  { id: 1, name: "Молоко" },
  { id: 5, name: "Хлеб" },
  { id: 3, name: "Масло" }
];

const hasItem5 = cart.some(item => item.id === 5);
console.log(hasItem5); // → true (Хлеб есть в корзине)

✅ every: все ли подходят?

every — строгий брат some. Он возвращает true, только если каждый элемент массива прошёл проверку. Если хотя бы один не прошёл — сразу false.

every тоже умеет «выходить раньше времени»: как только встретил элемент, не прошедший проверку — сразу возвращает false.

const scores = [85, 92, 78, 95, 88];

// Все ли оценки выше 70?
const allPass = scores.every(score => score >= 70);
console.log(allPass); // → true

// Все ли оценки выше 90?
const allExcellent = scores.every(score => score >= 90);
console.log(allExcellent); // → false (78 и 85 не проходят)

// Проверка прав доступа — важный кейс
const permissions = ["read", "write", "delete"];
const required = ["read", "write"];

const hasAccess = required.every(perm => permissions.includes(perm));
console.log(hasAccess); // → true (все нужные права есть)

🔑 Запомните пару some/every: some — логическое ИЛИ (хоть один). every — логическое И (все). Если массив пустой: [].some(fn) вернёт false, а [].every(fn) вернёт true (математическая конвенция).

📊 Таблица сравнения: когда что использовать

🔽
filter

Вернёт новый массив из всех подходящих элементов. Нужно несколько результатов.

🔍
find

Вернёт один элемент (первый подходящий) или undefined. Нужен конкретный объект.

🤔
some

Вернёт true/false. Нужно знать: есть ли хотя бы один подходящий?

✅
every

Вернёт true/false. Нужно знать: все ли элементы подходят под условие?

// Сценарий: интернет-магазин
const items = [
  { name: "Яблоко", price: 50, organic: true },
  { name: "Банан", price: 30, organic: false },
  { name: "Морковь", price: 40, organic: true },
  { name: "Молоко", price: 80, organic: false }
];

// filter: все органические товары
const organicItems = items.filter(i => i.organic);
// → [{ Яблоко }, { Морковь }]

// find: первый товар дешевле 45 руб.
const cheap = items.find(i => i.price < 45);
// → { name: "Яблоко", price: 50... } нет, первый < 45 — Банан (30)
// → { name: "Банан", price: 30, organic: false }

// some: есть ли неорганические товары?
const hasNonOrganic = items.some(i => !i.organic);
// → true

// every: все ли товары дешевле 100 руб.?
const allCheap = items.every(i => i.price < 100);
// → true

✅ Итоги урока

  • filter — создаёт новый массив из элементов, для которых колбэк вернул true
  • find — возвращает первый элемент, прошедший проверку, или undefined
  • some — возвращает true, если хотя бы один элемент прошёл проверку
  • every — возвращает true, если все элементы прошли проверку
  • Все четыре метода принимают колбэк-предикат (возвращает true/false) и не изменяют исходный массив
  • some и every «умные» — останавливаются, как только могут дать ответ
  • Всегда проверяйте результат find на undefined перед использованием

В следующем уроке — reduce: самый мощный и гибкий метод массивов, который может заменить любой из изученных (и много чего ещё). 🔥

filter, find, some, every

7 вопросов

Фильтрация товаров по цене

Дан массив товаров products с полями { name, price, inStock }. Используя filter, верните массив названий товаров, которые есть в наличии (inStock === true) и стоят меньше 1000.

Проверка массива через some и every

Напишите функцию analyzeArray, которая принимает массив чисел и возвращает объект со свойствами: allPositive (true, если все числа > 0), hasNegative (true, если хотя бы одно число < 0), hasZero (true, если хотя бы одно число === 0). Используйте методы some и every.