Пошук уроків, статей та іншого контенту
Освоїте пошук елементів і перевірку умов за допомогою includes, indexOf, find і findIndex.
JavaScript надає кілька методів для пошуку значень у масиві:
includes() — перевіряє, чи містить масив конкретне значення;
indexOf() — повертає індекс першого знайденого значення;
find() — повертає перший елемент, який відповідає умові;
findIndex() — повертає індекс першого елемента, який відповідає умові.
Ці методи не змінюють початковий масив.
includes()Метод includes() перевіряє наявність конкретного значення в масиві. Результатом завжди є true або false.
const languages = ["JavaScript", "Python", "Java"];
console.log(languages.includes("Python")); // true
console.log(languages.includes("C++")); // falseМетод чутливий до регістру:
const fruits = ["Apple", "Banana", "Orange"];
console.log(fruits.includes("Apple")); // true
console.log(fruits.includes("apple")); // falseДругий аргумент визначає індекс, з якого потрібно почати пошук:
const numbers = [10, 20, 30, 20, 40];
console.log(numbers.includes(20)); // true
console.log(numbers.includes(20, 2)); // true
console.log(numbers.includes(20, 3)); // true
console.log(numbers.includes(20, 4)); // falseУ цьому прикладі:
пошук 20 у всьому масиві знаходить значення;
пошук із індексу 2 також знаходить 20 на індексі 3;
пошук із індексу 4 не знаходить значення.
includes() і NaNНа відміну від деяких інших способів порівняння, includes() правильно знаходить NaN:
const values = [1, 2, NaN, 4];
console.log(values.includes(NaN)); // trueindexOf()Метод indexOf() повертає індекс першого елемента, який дорівнює переданому значенню.
Якщо значення не знайдено, метод повертає -1.
const colors = ["red", "green", "blue", "green"];
console.log(colors.indexOf("green")); // 1
console.log(colors.indexOf("yellow")); // -1Якщо значення повторюється, повертається індекс його першого входження:
const numbers = [5, 10, 15, 10, 20];
console.log(numbers.indexOf(10)); // 1Як і includes(), indexOf() може приймати початковий індекс:
const numbers = [5, 10, 15, 10, 20];
console.log(numbers.indexOf(10)); // 1
console.log(numbers.indexOf(10, 2)); // 3
console.log(numbers.indexOf(10, 4)); // -1indexOf()До появи includes() наявність елемента часто перевіряли за допомогою indexOf():
const roles = ["admin", "editor", "user"];
if (roles.indexOf("editor") !== -1) {
console.log("Роль знайдено");
}Сьогодні для простої перевірки наявності читабельніше використовувати includes():
if (roles.includes("editor")) {
console.log("Роль знайдено");
}indexOf() використовує строге порівняння. Значення різних типів не вважаються однаковими:
const values = [1, 2, 3];
console.log(values.indexOf(2)); // 1
console.log(values.indexOf("2")); // -1Метод також не знаходить NaN:
const values = [NaN];
console.log(values.indexOf(NaN)); // -1find()Методи includes() і indexOf() шукають конкретне значення. Але часто потрібно знайти об'єкт, який відповідає певній умові.
Для цього використовується find().
Метод приймає callback-функцію, яку JavaScript викликає для кожного елемента масиву. Callback має повернути умову:
const users = [
{ id: 1, name: "Олена", isActive: false },
{ id: 2, name: "Андрій", isActive: true },
{ id: 3, name: "Марія", isActive: true },
];
const activeUser = users.find((user) => user.isActive);
console.log(activeUser);
// { id: 2, name: "Андрій", isActive: true }find() зупиняє пошук після першого елемента, для якого callback повернув true.
const products = [
{ name: "Ноутбук", price: 50000 },
{ name: "Мишка", price: 800 },
{ name: "Монітор", price: 12000 },
];
const affordableProduct = products.find((product) => product.price < 1000);
console.log(affordableProduct);
// { name: "Мишка", price: 800 }У callback можна поєднувати кілька умов:
const courses = [
{ title: "JavaScript", level: "beginner", duration: 20 },
{ title: "React", level: "intermediate", duration: 30 },
{ title: "Node.js", level: "intermediate", duration: 25 },
];
const course = courses.find(
(course) => course.level === "intermediate" && course.duration < 30
);
console.log(course);
// { title: "Node.js", level: "intermediate", duration: 25 }Якщо жоден елемент не відповідає умові, find() повертає undefined:
const numbers = [2, 4, 6];
const result = numbers.find((number) => number > 10);
console.log(result); // undefinedПеред використанням властивостей знайденого об'єкта варто перевірити результат:
const users = [
{ id: 1, name: "Олена" },
{ id: 2, name: "Андрій" },
];
const user = users.find((user) => user.id === 5);
if (user) {
console.log(user.name);
} else {
console.log("Користувача не знайдено");
}За потреби можна використати оператор опціонального ланцюжка:
const user = users.find((user) => user.id === 5);
console.log(user?.name); // undefinedfindIndex()Метод findIndex() працює подібно до find(), але повертає не сам елемент, а його індекс.
const users = [
{ id: 101, name: "Олена" },
{ id: 102, name: "Андрій" },
{ id: 103, name: "Марія" },
];
const userIndex = users.findIndex((user) => user.id === 102);
console.log(userIndex); // 1Якщо відповідного елемента немає, метод повертає -1:
const userIndex = users.findIndex((user) => user.id === 999);
console.log(userIndex); // -1findIndex()findIndex() зручно використовувати, якщо потрібно:
перевірити наявність елемента за складною умовою;
отримати його позицію;
замінити або видалити елемент за індексом;
оновити дані в масиві.
Наприклад, оновимо статус користувача:
const users = [
{ id: 1, name: "Олена", isActive: false },
{ id: 2, name: "Андрій", isActive: true },
];
const userIndex = users.findIndex((user) => user.id === 1);
if (userIndex !== -1) {
users[userIndex].isActive = true;
}
console.log(users);
// [
// { id: 1, name: "Олена", isActive: true },
// { id: 2, name: "Андрій", isActive: true }
// ]Вибір методу залежить від того, що саме потрібно отримати:
потрібна відповідь «є значення чи немає» — includes();
потрібен індекс конкретного значення — indexOf();
потрібен сам елемент за умовою — find();
потрібен індекс елемента за умовою — findIndex().
const numbers = [4, 8, 15, 16, 23, 42];
const hasNumber = numbers.includes(15);
const numberIndex = numbers.indexOf(15);
const largeNumber = numbers.find((number) => number > 20);
const largeNumberIndex = numbers.findIndex((number) => number > 20);
console.log(hasNumber); // true
console.log(numberIndex); // 2
console.log(largeNumber); // 23
console.log(largeNumberIndex); // 4Для масиву примітивних значень можна передати значення безпосередньо:
const tags = ["javascript", "frontend", "web"];
console.log(tags.includes("frontend")); // trueДля масиву об'єктів потрібно перевіряти властивість об'єкта за допомогою callback:
const tasks = [
{ id: 1, title: "Вивчити змінні", completed: true },
{ id: 2, title: "Повторити масиви", completed: false },
{ id: 3, title: "Розв'язати вправи", completed: false },
];
const task = tasks.find((task) => task.id === 2);
const taskIndex = tasks.findIndex((task) => task.title === "Розв'язати вправи");
console.log(task);
// { id: 2, title: "Повторити масиви", completed: false }
console.log(taskIndex); // 2Об'єкти порівнюються за посиланням, а не за вмістом:
const firstUser = { id: 1, name: "Олена" };
const secondUser = { id: 1, name: "Олена" };
const users = [firstUser];
console.log(users.includes(firstUser)); // true
console.log(users.includes(secondUser)); // falseХоча об'єкти мають однакові властивості, це різні об'єкти в пам'яті. Для пошуку за властивістю використовуйте find():
const user = users.find((user) => user.id === secondUser.id);
console.log(user); // { id: 1, name: "Олена" }find() і findIndex()Callback може отримувати три аргументи:
поточний елемент;
його індекс;
увесь масив.
const numbers = [10, 20, 30, 40];
const result = numbers.find((number, index, array) => {
console.log(`Елемент: ${number}, індекс: ${index}`);
console.log(`Довжина масиву: ${array.length}`);
return number > 25;
});
console.log(result); // 30На практиці найчастіше використовується лише перший аргумент:
const result = numbers.find((number) => number > 25);Розглянемо пошук товарів у каталозі:
const products = [
{ id: 1, title: "Клавіатура", category: "accessories", stock: 12 },
{ id: 2, title: "Ноутбук", category: "computers", stock: 0 },
{ id: 3, title: "Навушники", category: "accessories", stock: 8 },
];
const productIds = products.map((product) => product.id);
console.log(productIds.includes(3)); // true
const laptopIndex = products.findIndex((product) => product.title === "Ноутбук");
if (laptopIndex !== -1) {
console.log(`Індекс ноутбука: ${laptopIndex}`);
}
const availableAccessory = products.find(
(product) => product.category === "accessories" && product.stock > 0
);
console.log(availableAccessory);
// { id: 1, title: "Клавіатура", category: "accessories", stock: 12 }У цьому прикладі:
includes() перевіряє, чи існує ідентифікатор товару;
findIndex() знаходить позицію товару;
find() повертає перший доступний товар потрібної категорії.
Неправильно:
const numbers = [10, 20, 30];
const index = numbers.indexOf(10);
if (index) {
console.log("Значення знайдено");
}Індекс першого елемента дорівнює 0, а 0 є хибним значенням у JavaScript. Тому умова не виконається.
Правильно:
if (index !== -1) {
console.log("Значення знайдено");
}find() і findIndex()const numbers = [10, 20, 30];
const value = numbers.find((number) => number > 15);
const index = numbers.findIndex((number) => number > 15);
console.log(value); // 20
console.log(index); // 1find() повертає елемент, а findIndex() — його індекс.
find() поверне всі збігиfind() повертає лише перший знайдений елемент:
const numbers = [2, 4, 6, 8];
const result = numbers.find((number) => number % 2 === 0);
console.log(result); // 2Якщо потрібно отримати всі елементи, які відповідають умові, використовуйте filter():
const evenNumbers = numbers.filter((number) => number % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8]return у callbackУ фігурних дужках callback потрібно явно повертати результат:
const numbers = [5, 10, 15];
const result = numbers.find((number) => {
return number > 9;
});
console.log(result); // 10Без return callback повертатиме undefined:
const result = numbers.find((number) => {
number > 9;
});
console.log(result); // undefinedБез фігурних дужок результат повертається неявно:
const result = numbers.find((number) => number > 9);
console.log(result); // 10includes() для пошуку за властивістюНеправильно:
const users = [
{ id: 1, name: "Олена" },
{ id: 2, name: "Андрій" },
];
console.log(users.includes({ id: 1, name: "Олена" })); // falseДля пошуку об'єкта за властивістю потрібно використовувати find():
const user = users.find((user) => user.id === 1);
console.log(user); // { id: 1, name: "Олена" }Перевірте, чи містить масив ["html", "css", "javascript"] значення "javascript".
Знайдіть індекс числа 42 у масиві [10, 42, 7, 42].
Знайдіть перший товар із ціною понад 1000.
Знайдіть індекс користувача з конкретним id.
Обробіть випадок, коли find() не знайшов елемент.
Поясніть, чому перевірка if (array.indexOf(value)) може працювати неправильно.
includes() повертає true або false і підходить для перевірки наявності конкретного значення.
indexOf() повертає індекс першого збігу або -1, якщо значення не знайдено.
find() повертає перший елемент, який відповідає умові, або undefined.
findIndex() повертає індекс першого елемента, який відповідає умові, або -1.
Для масивів об'єктів зазвичай використовують find() і findIndex() з перевіркою властивостей.
Для простої перевірки індексу потрібно порівнювати результат із -1.
find() знаходить лише перший збіг, а для пошуку всіх збігів використовується filter().