Метод indexOf в массиве объектов? - PullRequest
445 голосов
/ 29 декабря 2011

Какой лучший способ получить индекс массива, который содержит объекты?

Представьте себе этот сценарий:

var hello = {
    hello: 'world',
    foo: 'bar'
};
var qaz = {
    hello: 'stevie',
    foo: 'baz'
}

var myArray = [];
myArray.push(hello,qaz);

Теперь я хотел бы иметь indexOf объект, свойство hello которого равно 'stevie', которое в этом примере будет 1.

Я довольно новичок в JavaScript, и я не знаю, существует ли простой метод или мне нужно создать собственную функцию для этого.

Ответы [ 27 ]

4 голосов
/ 12 июня 2014
array.filter(function(item, indx, arr){ return(item.hello === 'stevie'); })[0];

Ума [0].

Правильно использовать reduce, как в ответе Antonio Laguna.

Извиняюсь за краткость ...

3 голосов
/ 18 мая 2016

простой:

myArray.indexOf(myArray.filter(function(item) {
    return item.hello == "stevie"
})[0])
3 голосов
/ 12 апреля 2016

Попробуйте это:

console.log(Object.keys({foo:"_0_", bar:"_1_"}).indexOf("bar"));

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

3 голосов
/ 17 декабря 2016

Если вас интересует только поиск позиции, см. @ ответ Пабло .

pos = myArray.map(function(e) { return e.hello; }).indexOf('stevie');

Однако, если вы с нетерпением ждете поискаэлемент (т. е. если вы хотели сделать что-то подобное myArray[pos]), существует более эффективный однострочный способ сделать это, используя filter.

element = myArray.filter((e) => e.hello === 'stevie')[0];

См. Результаты производительности (~ + 42% операций в секунду): http://jsbench.github.io/#7fa01f89a5dc5cc3bee79abfde80cdb3

2 голосов
/ 21 марта 2016

Furthor of @ Monika Garg answer , вы можете использовать findIndex() (Для браузеров без поддержки polyfill .

Я видел, что люди отвергли этот ответ, и я надеюсь, что они сделали это из-за неправильного синтаксиса, потому что, на мой взгляд, это самый элегантный способ.

Метод findIndex () возвращает индексв массиве, если элемент в массиве удовлетворяет предоставленной функции тестирования.В противном случае возвращается -1.

Например:

var hello = {
  hello: 'world',
  foo: 'bar'
};
var qaz = {
  hello: 'stevie',
  foo: 'baz'
}

var myArray = [];
myArray.push(hello,qaz);

var index = myArray.findIndex(function(element) {
  return element.hello == 'stevie';
});

alert(index);
2 голосов
/ 04 февраля 2016

Используя метод ES6 findIndex , без lodash или любых других библиотек, вы можете написать:

function deepIndexOf(arr, obj) {
  return arr.findIndex(function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}

Это сравнит непосредственные свойства объекта, но не вернется в свойства.

Если ваша реализация пока не предоставляет findIndex (большинство не предоставляют), вы можете добавить легкий полифилл, поддерживающий этот поиск:

function deepIndexOf(arr, obj) {
  function findIndex = Array.prototype.findIndex || function (pred) {
    for (let i = 0; i < this.length; ++i) {
      if (pred.call(this, this[i], i)) {
        return i;
      }
    }

    return -1;
  }

  return findIndex.call(arr, function (cur) {
    return Object.keys(obj).every(function (key) {
      return obj[key] === cur[key];
    });
  });
}

(из моего ответа на этот дурак )

2 голосов
/ 18 мая 2015

Использование _.findIndex из библиотеки underscore.js

Вот пример _.findIndex([{a:1},{a: 2,c:10},{a: 3}], {a:2,c:10}) //1

2 голосов
/ 10 июня 2016

Вы можете использовать встроенную и удобную функцию Array.prototype.findIndex(), в основном:

Метод findIndex () возвращает индекс в массиве, если элемент в массиве удовлетворяет предоставленной функции тестирования.В противном случае возвращается -1.

Только примечание, которое не поддерживается в Internet Explorer, Opera и Safari, но вы можете использовать Polyfill, предоставленный по ссылке ниже.

Дополнительная информация:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

var hello = {
  hello: 'world',
  foo: 'bar'
};
var qaz = {
  hello: 'stevie',
  foo: 'baz'
}

var myArray = [];
myArray.push(hello, qaz);

var index = myArray.findIndex(function(element, index, array) {
  if (element.hello === 'stevie') {
    return true;
  }
});
alert('stevie is at index: ' + index);
2 голосов
/ 25 августа 2014

Я сделал универсальную функцию, чтобы проверить приведенный ниже код и работает для любого объекта

function indexOfExt(list, item) {
    var len = list.length;

    for (var i = 0; i < len; i++) {
        var keys = Object.keys(list[i]);
        var flg = true;
        for (var j = 0; j < keys.length; j++) {
            var value = list[i][keys[j]];
            if (item[keys[j]] !== value) {
                flg = false;
            }
        }
        if (flg == true) {
            return i;
        }
    }
    return -1;
}

var items = [{ "hello": 'world', "foo": 'bar' }];
var selectedItem = { "hello": 'world', "foo": 'bar' };
alert(items.indexOf(selectedItem));
alert(indexOfExt(items, selectedItem));

Первое оповещение вернет -1 (значит, совпадение не найдено), а второе оповещение вернет 0 (значит совпадение найдено).

2 голосов
/ 09 февраля 2018

Если ваш объект - это тот же объект, который вы используете в массиве, вы сможете получить индекс объекта так же, как если бы это была строка.

var hello = {
    hello: 'world',
    foo: 'bar'
};
var qaz = {
    hello: 'stevie',
    foo: 'baz'
}

var qazCLONE = { // new object instance and same structure
    hello: 'stevie',
    foo: 'baz'
}

var myArray = [hello,qaz];

myArray.indexOf(qaz) // should return 1
myArray.indexOf(qazCLONE) // should return -1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...