Подтвердить что ты не робот

Получить индекс объекта внутри массива, соответствующий условию

У меня такой массив:

[{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"},...]

Как я могу получить индекс объекта, который соответствует условию, без итерации по всему массиву?

Например, учитывая prop2=="yutu", я хочу получить индекс 1.

Я видел .indexOf() но думаю, что он используется для простых массивов, таких как ["a1","a2",...]. Я также проверил $.grep() но это возвращает объекты, а не индекс.

4b9b3361

Ответ 1

Начиная с 2016 года, вы должны использовать Array.findIndex (стандарт ES2015/ES6) для этого:

a = [
  {prop1:"abc",prop2:"qwe"},
  {prop1:"bnmb",prop2:"yutu"},
  {prop1:"zxvz",prop2:"qwrq"}];
    
index = a.findIndex(x => x.prop2 ==="yutu");

console.log(index);

Ответ 2

Как я могу получить индекс объекта, который соответствует условию (без итерации по массиву)?

Вы не можете, что-то должно проходить через массив (по крайней мере один раз).

Если условие сильно изменится, вам придется пройти через петлю и посмотреть на объекты в нем, чтобы увидеть, соответствуют ли они условию. Однако, в системе с функциями ES5 (или если вы устанавливаете прокладку), эту итерацию можно выполнить достаточно кратко:

var index;
yourArray.some(function(entry, i) {
    if (entry.prop2 == "yutu") {
        index = i;
        return true;
    }
});

Это использует новую функцию (ish) Array#some, которая перебирает элементы в массиве до тех пор, пока функция, которую вы ему даете, не вернет true. Функция, которую я дал, сохраняет индекс соответствующей записи, а затем возвращает true чтобы остановить итерацию.

Или, конечно, просто используйте цикл for. Различные варианты итераций рассматриваются в этом другом ответе.

Но если вы всегда будете использовать одно и то же свойство для этого поиска, и если значения свойств уникальны, вы можете выполнить цикл всего один раз и создать объект для их сопоставления:

var prop2map = {};
yourArray.forEach(function(entry) {
    prop2map[entry.prop2] = entry;
});

(Или, опять же, вы можете использовать цикл for или любой другой вариант.)

Затем, если вам нужно найти запись с prop2 = "yutu", вы можете сделать это:

var entry = prop2map["yutu"];

Я называю это "кросс-индексирование" массива. Естественно, если вы удаляете или добавляете записи (или изменяете их значения prop2), вам также необходимо обновить свой объект сопоставления.

Ответ 3

Что сказал TJ Crowder, у всех будет какая-то скрытая итерация, lodash будет:

var index = _.findIndex(array, {prop2: 'yutu'})

Ответ 4

var index;
yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' ? (index = i, true) : false;
});

Итерация по всем элементам массива. Он возвращает либо индекс, либо true или false, если условие не соответствует.

Важно явное возвращаемое значение true (или значение, которое имеет логический результат). Единственного назначения недостаточно, из-за возможного индекса с 0 (Boolean (0) === false), что не приведет к ошибке, но отключит прерывание итерации.

Изменить

Еще более короткая версия выше:

yourArray.some(function (elem, i) {
    return elem.prop2 === 'yutu' && ~(index = i);
});

Ответ 5

var CarId = 23;

//x.VehicleId property to match in the object array
var carIndex = CarsList.map(function (x) { return x.VehicleId; }).indexOf(CarId);

И для базовых номеров массивов вы также можете сделать это:

var numberList = [100,200,300,400,500];
var index = numberList.indexOf(200); // 1

Вы получите -1, если не сможете найти значение в массиве.

Ответ 6

Вы можете использовать Array.prototype.some() следующим образом (как упоминалось в других ответах):

https://jsfiddle.net/h1d69exj/2/

function findIndexInData(data, property, value) {
    var result = -1;
    data.some(function (item, i) {
        if (item[property] === value) {
            result = i;
            return true;
        }
    });
    return result;
}
var data = [{prop1:"abc",prop2:"qwe"},{prop1:"bnmb",prop2:"yutu"},{prop1:"zxvz",prop2:"qwrq"}]



alert(findIndexInData(data, 'prop2', "yutu")); // shows index of 1

Ответ 7

Я видел много решений в приведенном выше.

Здесь я использую функцию карты, чтобы найти индекс текста поиска в объекте массива.

Я собираюсь объяснить свой ответ с использованием данных студентов.

  • Шаг 1: создать объект массива для студентов (необязательно, вы можете создать свой собственный объект массива).
    var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];

  • Шаг 2. Создание переменной для поиска текста.
    var studentNameToSearch = "Divya";

  • Шаг 3: Создайте переменную для хранения совпадающего индекса (здесь мы используем функцию map для итерации).
    var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);

var students = [{name:"Rambabu",htno:"1245"},{name:"Divya",htno:"1246"},{name:"poojitha",htno:"1247"},{name:"magitha",htno:"1248"}];

var studentNameToSearch = "Divya";

var matchedIndex = students.map(function (obj) { return obj.name; }).indexOf(studentNameToSearch);

console.log(matchedIndex);

alert("Your search name index in array is:"+matchedIndex)

Ответ 8

Почему вы не хотите точно итерации? Новый Array.prototype.forEach отлично подходит для этой цели!

Вы можете использовать двоичное дерево поиска для поиска по одному вызову метода, если хотите. Это аккуратная реализация чернового дерева поиска и красного черного дерева в JS - https://github.com/vadimg/js_bintrees - но я не уверен, можете ли вы найти индекс в то же время.

Ответ 9

Один шаг с использованием Array.reduce() - no jQuery

var items = [{id: 331}, {id: 220}, {id: 872}];

var searchIndexForId = 220;
var index = items.reduce(function(searchIndex, item, index){
  if(item.id === searchIndexForId) { 
    console.log('found!');
    searchIndex = index;
  }
  return searchIndex;
}, null);

вернет null, если индекс не найден.

Ответ 10

function findIndexByKeyValue(_array, key, value) {
    for (var i = 0; i < _array.length; i++) { 
        if (_array[i][key] == value) {
            return i;
        }
    }
    return -1;
}
var a = [
    {prop1:"abc",prop2:"qwe"},
    {prop1:"bnmb",prop2:"yutu"},
    {prop1:"zxvz",prop2:"qwrq"}];
var index = findIndexByKeyValue(a, 'prop2', 'yutu');
console.log(index);

Ответ 11

var list =  [
                {prop1:"abc",prop2:"qwe"},
                {prop1:"bnmb",prop2:"yutu"},
                {prop1:"zxvz",prop2:"qwrq"}
            ];

var findProp = p => {
    var index = -1;
    $.each(list, (i, o) => {
        if(o.prop2 == p) {
            index = i;
            return false; // break
        }
    });
    return index; // -1 == not found, else == index
}

Ответ 12

Оптимизировать код:

var index;
yourArray.some(function(entry, i) {
    index = i;
    return entry.prop2 == "yutu";
});

Почему все они возвращают true и false.

Ответ 13

Георг уже упомянул, что ES6 для этого имеет Array.findIndex. И некоторые другие ответы обходятся для ES5 с использованием метода Array.some.

Еще один элегантный подход может быть

var index;
for(index = yourArray.length; index-- > 0 && yourArray[index].prop2 !== "yutu";);

В то же время я хотел бы подчеркнуть, что Array.some может быть реализован с использованием двоичной или другой эффективной методики поиска. Таким образом, он может работать лучше для цикла в каком-то браузере.

Ответ 14

let array = [
  {prop1: "abc", prop2:  "qwe"},
  {prop1: "bnmb", prop2: "yutu"},
  {prop1: "zxvz", prop2: "qwrq"}
]

let search = "bnmb";

let index = array.findIndex( item => {
   return ( item.prop1 === search )
})