Метод indexOf в массиве объектов?
Как можно просто и напрямую найти индекс элемента в массиве объектов, удовлетворяющего некоторому условию?
Например, дан следующий ввод:
var hello = { hello: 'world', foo: 'bar' };
var qaz = { hello: 'stevie', foo: 'baz' };
var myArray = [];
myArray.push(hello, qaz);
Как мне выполнить поиск в myArray
, чтобы найти индекс элемента, у которого свойство hello
равно 'stevie'
? В этом случае результат должен быть 1
.
5 ответ(ов)
В ES2015 это делается довольно просто:
myArray.map(x => x.hello).indexOf('stevie')
Однако, вероятно, будет лучше по производительности для больших массивов:
myArray.findIndex(x => x.hello === 'stevie')
Использование findIndex
предпочтительнее, так как оно прекращает поиск, как только находит первый подходящий элемент, что делает его более эффективным в случае больших массивов.
Мне нравится ответ Пабло, но стоит отметить, что методы Array#indexOf
и Array#map
не поддерживаются во всех браузерах. Библиотека Underscore использует нативный код, если он доступен, но также имеет резервные варианты. Плюс, в ней есть метод pluck
, который выполняет именно ту же функцию, что и анонимный метод map
Пабло.
var idx = _.chain(myArray).pluck("hello").indexOf("Stevie").value();
Этот код на JavaScript использует метод reduce
для поиска индекса элемента в массиве myArray
, у которого свойство hello
равно "stevie"
. Давайте разберем, как это работает.
Вот как устроен код:
var idx = myArray.reduce(function(cur, val, index) {
if (val.hello === "stevie" && cur === -1) {
return index;
}
return cur;
}, -1);
reduce
принимает два аргумента: первую функцию-аккумулятор и начальное значение для аккумулятора (в данном случае -1).- Внутри функции-аккумулятора три параметра:
cur
— текущее значение аккумулятора (в начале -1).val
— текущее значение элемента массива.index
— индекс текущего элемента в массиве.
- Сначала проверяем, равняется ли свойство
hello
текущего элемента строке"stevie"
и равно ли текущее значение аккумулятораcur
-1 (это условие позволяет нам находить только первый индекс, соответствующий условию). - Если оба условия истинны, то функция возвращает текущий индекс (он становится новым значением аккумулятора).
- Если условия не выполняются, возвращается текущее значение аккумулятора
cur
, которое по умолчанию будет -1, если нужный элемент не найден. - Таким образом, в конце выполнения
reduce
мы получаем индекс элемента, если он найден, или -1, если его нет в массиве.
Если у вас есть дополнительные вопросы, пожалуйста, уточните!
Вы можете добавить метод indexOfObject
в прототип массива, чтобы искать индекс объекта по заданному свойству и значению. Вот пример реализации:
Array.prototype.indexOfObject = function(property, value) {
for (var i = 0, len = this.length; i < len; i++) {
if (this[i][property] === value) return i;
}
return -1; // Возвращаем -1, если объект не найден
}
// Пример использования:
let myArr = [{ name: "john" }, { name: "stevie" }, { name: "jane" }];
let index = myArr.indexOfObject("name", "stevie");
console.log(index); // Выведет 1
Этот метод проходит по массиву и сравнивает значение указанного свойства объекта с заданным значением. Если совпадение найдено, возвращается индекс объекта, в противном случае возвращается -1.
Хотя большинство других ответов здесь являются валидными, иногда лучше создать короткую простую функцию рядом с тем местом, где вы собираетесь ее использовать.
// Обертка для indexOf для списка объектов
function indexOfbyKey(obj_list, key, value) {
for (let index in obj_list) {
if (obj_list[index][key] === value) return index;
}
return -1;
}
// Поиск строки в списке (по умолчанию -1)
var test1 = indexOfbyKey(object_list, 'name', 'Stevie');
var test2 = indexOfbyKey(object_list, 'last_name', 'some other name');
Это зависит от того, что для вас важно. Возможно, использование однострочного решения сэкономит строки кода и будет казаться очень умным, или размещение универсального решения где-то, что покрывает различные особые случаи. Но иногда лучше просто сказать: "я сделал это так", нежели оставлять будущим разработчикам дополнительную работу по обратной инженерии, особенно если вы считаете себя "новичком", как в вашем вопросе.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"