Для поиска индекса элемента в массиве можно использовать методы 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
Комментариев нет:
Отправить комментарий