Как найти индекс объекта внутри массива, используя underscore.js?
Я хочу получить индекс данного значения внутри массива, используя underscore.js.
Вот мой случай
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'};
Я использовал следующий код,
var index = _.indexOf(array, function(data) {
alert(data.toSource()); //For testing purpose
return data === searchValue;
});
Также пробовал это тоже
var index = _.indexOf(array, {id: searchValue.id});
Но это returns -1
. Поскольку он не входит в эту функцию. Поэтому я не получил это сообщение.
Что не так с моим кодом.
Может кто-нибудь мне помочь?
Ответы
Ответ 1
Используйте это вместо:
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'},
index = -1;
_.each(array, function(data, idx) {
if (_.isEqual(data, searchValue)) {
index = idx;
return;
}
});
console.log(index); //0
В вашем фрагменте data === searchValue
сравниваются ссылки объектов, вы не хотите этого делать. С другой стороны, если вы используете data == searchValue
, вы собираетесь сравнивать представления строк объектов, т.е. [Object object]
, если у вас нет переопределенных методов toString
.
Таким образом, правильный способ сравнения объектов - использовать _.isEqual
.
Ответ 2
Я бы очень хотел взглянуть на lodash. Он содержит довольно много отличных функций, которых, к сожалению, не хватает.
Например, это то, что вы сделали бы с lodash:
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'};
var index = _.findIndex(array, searchValue);
console.log(index === 0); //-> true
http://lodash.com/docs#findIndex
Кроме того, если вы обязаны использовать Underscore, вы можете захватить сборку lodash underscore в https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js
ES2015
Теперь, когда ES2015 широко используется (через транспилеры, такие как Babel), вы можете отказаться от lodash и подчеркивания для этой задачи и использовать собственные методы:
var arr = [{ id: 1 }, { id: 2}];
arr.findIndex(i => i.id === 1); // 0
Ответ 3
Возможно, мое предложение даст вам совет.
Почему вы используете обратный вызов для метода indexof? Подпись индекса в underscore.js следующая:
_.indexOf(array, value, [isSorted])
find может быть лучше для этой задачи:
_.find(array, function(item, index) {
if (item.id == searchValue.id) {
alert(index);
}
});
Ответ 4
С объектами, ===
и ==
проверьте, ссылаются ли две ссылки на объект тот же; он не проверяет эквивалентные объекты:
var a = {foo: "bar"};
var b = {foo: "bar"};
console.log(a === b); // false, `a` and `b` refer to different (but equivalent) objects
a = b = {something: "here"};
console.log(a === b); // true, `a` and `b` refer to the *same* object
Вы должны проверить свойства объекта, чтобы принять решение. В вашем случае свойство id
выглядит как хорошая опция или если вы хотите сравнить все свойства, вы можете использовать Underscore isEqual
.
Ответ 5
Подчеркивание использует собственный метод indexOf, если он доступен, иначе применяется резервное копирование. Таким образом, для списка объектов вы должны реализовать его каким-либо другим способом.
Одним из примеров может быть
_.chain(array).pluck("key").indexOf("value").value();
или
_.map(array,function(e) { return e.key; }).indexOf(value);
Ответ 6
_.find(array, function(item, index) {
if (item.id == searchValue.id) {
alert(index);
}
});
Ответ 7
Если у вас есть сложные объекты и вы хотите найти один объект в коллекции, ищущий определенное свойство, просто перейдите по ссылке:
_.indexOf(arrayObj, _.findWhere(arrayObj, {id: 1}) );
Где "arrayObj" - это коллекция с объектами, "id" - это prop, а "1" - это значение, находящееся в поиске.