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

485
20 декабря 2017, 23:50

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

Answer 1

Варианты:

  1. Использовать findIndex, которая в качестве параметра принимает callback функцию, в которой можно указать условия.

    Её можно использовать для поиска непримитивных типов (в т.ч. объектов), а также где можно/нужно задать более сложные условия, нежели просто значение. Если элемент не найден — возвращается -1.

    let searchName = 'barry';
    let index = inputArr.findIndex(el => el.name === searchName);
    

    Кстати, плюс этого метода: найдя нужный элемент — итерация по массиву прекращается. То есть если массив из 100 элементов и найден индекс 3, то остальные 97 итераций не происходят.

  1. Вариант с map для массива. В чём идея:

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

    Пример:

    let searchName = 'barry';
    let index = inputArr.map(el => el.name).indexOf(searchName);
    

    Недостаток: map создает целый массив, в котором лежат эдементы с нужным property. Поэтому если в массиве, например 1000 элементов, то может сказаться на производительности.

    Плюс: в отличие от findIndex - map поддерживают больше браузеров, т.к. это более старый метод для работы с массивами

  1. Для немодерновых браузеров, которые не умеют в 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);
    
  1. Если интересуют библиотеки, то в 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
    
READ ALSO
Вывод массива в таблицу js

Вывод массива в таблицу js

Создать массив объектов студент который имеет: ID, Name, Surname, Age, Avarage (средняя оценка) Отобразить этот массив в виде таблицы

264
Ошибка Uncaught TypeError: Illegal invocation

Ошибка Uncaught TypeError: Illegal invocation

При выполнении выходит ошибка Uncaught TypeError: Illegal invocation

1139
Помогите разобраться с js

Помогите разобраться с js

Mне нужно сделать, чтобы пользователи могли добавлять свои банеры на сайт, но форма появлялась после клика по одному из уже имеющихся банеровКак...

292
Динамически добавлять svg спрайт

Динамически добавлять svg спрайт

Столкнулся с проблемой, что когда динамически добавлять svg спрайт то он не показывается, то есть svg и внутренний тег use видны в консоли, а вот...

262