Страницы

Поиск по вопросам

вторник, 21 мая 2019 г.

Как найти индекс элемента в массиве объектов?

Для поиска индекса элемента в массиве можно использовать методы indexOf (для первого вхождения) и lastIndexOf (для последнего вхождения).
А как можно найти индекс в массиве объектов? Например индекс при первом вхождении нужного объекта?
Например есть массив объектов:
let inputArr = [{name:'bruce', age:40, city:'gotham'}, {name:'barry', age:25, city:'fallville'}, {name:'diana', age:30, city:'themyscira'} ];
Как получить индекс, где в свойстве name значение barry? Если писать так:
inputArr.indexOf('barry');
то выведет -1, а ожидаемое значение — 1. Может циклом перебирать все значения? Может есть простые способы?

orig post https://stackoverflow.com/q/8668174/6104996


Ответ

Варианты:
Использовать findIndex, которая в качестве параметра принимает callback функцию, в которой можно указать условия.
Её можно использовать для поиска непримитивных типов (в т.ч. объектов), а также где можно/нужно задать более сложные условия, нежели просто значение. Если элемент не найден — возвращается -1
let searchName = 'barry'; let index = inputArr.findIndex(el => el.name === searchName);
Кстати, плюс этого метода: найдя нужный элемент — итерация по массиву прекращается. То есть если массив из 100 элементов и найден индекс 3, то остальные 97 итераций не происходят.

Вариант с map для массива. В чём идея:
Пробежаться с помощью map, выбрав в массив нужные значения по указанному свойству Уже к этому массиву и применять indexOf

Пример:
let searchName = 'barry'; let index = inputArr.map(el => el.name).indexOf(searchName);
Недостаток: map создает целый массив, в котором лежат эдементы с нужным property. Поэтому если в массиве, например 1000 элементов, то может сказаться на производительности.
Плюс: в отличие от findIndex - map поддерживают больше браузеров, т.к. это более старый метод для работы с массивами

Для немодерновых браузеров, которые не умеют в findIndex, например IE8 (9,10,11), придется делать цикл. Одно замечание: нужно делать не цикл for...in, а обычный for, чтобы в любой момент при нахождении элемента можно было сразу прервать цикл, чтобы не работал вхолостую
function arrayObjectIndexOf(myArray, property, searchTerm) { for(let i = 0, len = myArray.length; i < len; i++) { if (myArray[i][property] === searchTerm) return i; }
return -1; }
let index = arrayObjectIndexOf(inputArr, 'name', searchName); console.log(index);

Если интересуют библиотеки, то в underscore.js library, есть метод _.findIndex
var index = _.findIndex(inputArr, {name:searchName}) // 1
Можно задать несколько условий (как и при использовании findIndex), например:
let inputArr = [{a:1}, {a:2, c:10}, {a:3}, {a:2, c:12}, {a:2, c:8}]; let cond = {a:2,c:12}; var index = _.findIndex(inputArr, cond) console.log(index); // 3

Комментариев нет:

Отправить комментарий