FindIndex: примеры (JAVASCRIPT)
findIndex(callback: function, thisArg?: any): numberОсновы метода findIndex
Array.prototype.findIndex()
– это метод JavaScript для поиска индекса первого элемента в массиве, который удовлетворяет заданному условию, реализованному в функции-колбэке. Если элемент не найден, метод возвращает -1. Он не изменяет исходный массив.Метод применяется, когда требуется найти позицию элемента по сложному критерию, а не просто по значению (для чего подходит indexOf()).
Синтаксис: arr.findIndex(callback(element[, index[, array]])[, thisArg]).
- callback – функция, выполняющаяся для каждого элемента. Должна возвращать true для элемента, который прошёл проверку.
- element – текущий обрабатываемый элемент.
- index (необязательный) – индекс текущего элемента.
- array (необязательный) – массив, по которому осуществляется проход.
- thisArg (необязательный) – значение, используемое в качестве this при выполнении колбэка.
Возвращаемое значение: индекс первого элемента, прошедшего проверку, или -1, если такой элемент не найден.
Простые примеры использования
Пример 1: Поиск индекса числа больше 10.
const numbers = [5, 12, 8, 130, 44];
const result = numbers.findIndex(num => num > 10);
console.log(result);// 1 (первый элемент, удовлетворяющий условию, это 12 с индексом 1)
Пример 2: Поиск индекса объекта по свойству.
const fruits = [
{name: 'яблоки', quantity: 2},
{name: 'бананы', quantity: 0},
{name: 'вишни', quantity: 5}
];
const result = fruits.findIndex(fruit => fruit.name === 'вишни');
console.log(result);// 2
Пример 3: Использование всех параметров колбэка и thisArg.
function isPrime(element, index, array) {
let start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return element > 1;
}
const numbers = [4, 6, 8, 9, 11];
const result = numbers.findIndex(isPrime);
console.log(result);// 4 (число 11 простое, его индекс 4)
Пример 4: Элемент не найден.
const result = [1, 2, 3].findIndex(num => num > 5);
console.log(result);// -1
Похожие методы в JavaScript
- indexOf() / lastIndexOf(): Ищут индекс элемента по строгому равенству (===). Не принимают функцию для сложных условий. Предпочтительны для поиска примитивных значений.
- find(): Аналогичен findIndex(), но возвращает сам найденный элемент или undefined. Выбирают в зависимости от того, нужен элемент или его позиция.
- some(): Проверяет, удовлетворяет ли хотя бы один элемент условию. Возвращает true/false. Используют, когда важен факт наличия, а не индекс.
- Array.filter() + indexOf(): Комбинация для поиска всех индексов элементов, удовлетворяющих условию. Требует больше ресурсов.
Типичные ошибки
1. Колбэк не возвращает булево значение.
// Колбэк ничего не возвращает (возвращает undefined)
const arr = [1, 2, 3];
const index = arr.findIndex(item => { item > 1; }); // Нет return
console.log(index);// -1 (для всех элементов возвращается undefined, что интерпретируется как false)
2. Попытка использования для поиска NaN.
console.log([NaN].indexOf(NaN)); // -1 (не находит)
console.log([NaN].findIndex(x => Number.isNaN(x))); // 0 (корректно)// indexOf не может найти NaN, findIndex решает эту проблему
3. Мутация массива внутри колбэка может привести к непредсказуемому поведению.
const arr = [1, 2, 3, 4];
const index = arr.findIndex((num, i, array) => {
array.pop(); // Изменяем массив в процессе итерации
return num > 2;
});
console.log(index, arr);// Результат может различаться в зависимости от движка JS
4. Поиск в разреженном массиве.
const sparseArray = [1, , , 4];
const index = sparseArray.findIndex(x => x === undefined);
console.log(index);// 1 (пропущенные элементы обрабатываются как undefined)
История изменений
Метод findIndex() был добавлен в спецификацию ECMAScript 2015 (ES6). С тех пор его поведение остается стабильным.
Важные аспекты реализации: метод является универсальным и может быть вызван для любого массивоподобного объекта, у которого есть свойство length и индексированные свойства (например, NodeList, arguments).
Поддержка в браузерах: полная поддержка во всех современных браузерах, включая Internet Explorer (не поддерживается). Для старых сред может потребоваться полифил.
Расширенные примеры
Пример 1: Поиск с использованием контекста (thisArg).
class Searcher {
constructor(target) {
this.target = target;
}
check(value) {
return value === this.target;
}
}
const array = ['a', 'b', 'c'];
const searcher = new Searcher('b');
const index = array.findIndex(function(item) {
return this.check(item);
}, searcher);
console.log(index); // 1// 1
Пример 2: Поиск индекса в массиве объектов с несколькими условиями.
const users = [
{id: 1, name: 'Анна', active: true},
{id: 2, name: 'Борис', active: false},
{id: 3, name: 'Анна', active: true}
];
const index = users.findIndex(u => u.name === 'Анна' && u.active);
console.log(index); // 0 (первая активная Анна)// 0
Пример 3: Поиск индекса в части массива (имитация параметра fromIndex).
function findIndexFrom(array, predicate, fromIndex = 0) {
const subArray = array.slice(fromIndex);
const foundIndex = subArray.findIndex(predicate);
return foundIndex === -1 ? -1 : foundIndex + fromIndex;
}
const arr = [1, 2, 3, 2, 1];
const idx = findIndexFrom(arr, x => x === 2, 2);
console.log(idx); // 3 (второе вхождение двойки)// 3
Пример 4: Поиск индекса в массиве с использованием сторонней библиотеки (например, Lodash) не требуется, но для сложных условий можно использовать findIndex с сложным колбэком.
const data = [
{values: [1, 2]},
{values: [3, 4, 5]},
{values: [6]}
];
const index = data.findIndex(obj => obj.values.includes(4));
console.log(index); // 1// 1
Пример 5: Обработка edge-case с пустым массивом и массивом из одного элемента.
console.log([].findIndex(x => true)); // -1
console.log([undefined].findIndex(x => x === undefined)); // 0
console.log([null].findIndex(x => x == null)); // 0// -1 // 0 // 0
Аналоги в других языках программирования
Python: Используют метод index() в списках с генератором или циклом. Прямого аналога нет, но можно использовать next() с enumerate().
# Пример поиска индекса первого четного числа
numbers = [1, 3, 5, 8, 9]
try:
index = next(i for i, num in enumerate(numbers) if num % 2 == 0)
print(index)
except StopIteration:
print(-1)# 3
PHP: Функция array_search() с флагом strict или array_filter() с key().
// Поиск индекса по значению с array_search()
$array = ['a' => 5, 'b' => 12, 'c' => 8];
$key = array_search(12, $array); // 'b'
// Для сложных условий используют array_filter()
$filtered = array_filter($array, function($val) { return $val > 10; });
$keys = array_keys($filtered); // ['b']// Возвращает ключ 'b', а не числовой индекс
C# (LINQ): Метод FindIndex() у List
List numbers = new List {5, 12, 8, 130, 44};
int index = numbers.FindIndex(num => num > 10); // 1 SQL: Нет прямого аналога, но для поиска позиции в результате запроса можно использовать ROW_NUMBER().