В массиве объектов самый быстрый способ найти индекс объекта, атрибуты которого соответствуют поиску
Я занимался серфингом вокруг немного, пытаясь найти эффективный способ сделать это, но нигде не стал. У меня есть массив объектов, который выглядит так:
array[i].id = some number;
array[i].name = some name;
Что я хочу сделать, так это найти ИНДЕКСЫ объектов, где id равен, например, один из 0,1,2,3 или 4.
Полагаю, я мог бы сделать что-то вроде:
var indexes = [];
for(i=0; i<array.length; i++) {
(array[i].id === 0) ? { indexes[0] = i }
(array[i].id === 1) ? { indexes[1] = i }
(array[i].id === 2) ? { indexes[2] = i }
(array[i].id === 3) ? { indexes[3] = i }
(array[i].id === 4) ? { indexes[4] = i }
}
Пока это будет работать, оно выглядит довольно дорогостоящим и медленным (не говоря уже о уродливом), особенно если array.length может быть большим. Любые идеи о том, как это сделать? Я думал об использовании array.indexOf, но я не вижу, как заставить синтаксис. Это
array.indexOf(this.id === 0);
например, возвращает undefined, как и должно быть.
Спасибо заранее!
Ответы
Ответ 1
Возможно, вы хотели бы использовать функции более высокого порядка, такие как "карта".
Предполагая, что вы хотите искать по атрибуту 'field':
var elementPos = array.map(function(x) {return x.id; }).indexOf(idYourAreLookingFor);
var objectFound = array[elementPos];
Ответ 2
Самый простой и простой способ найти индекс элемента в массиве.
Синтаксис ES5: [{id:1},{id:2},{id:3},{id:4}].findIndex(function(obj){return obj.id == 3})
Синтаксис ES6: [{id:1},{id:2},{id:3},{id:4}].findIndex(obj => obj.id == 3)
Ответ 3
Новый метод Array . filter() будет хорошо работать для этого:
var filteredArray = array.filter(function (element) {
return element.id === 0;
});
jQuery также может сделать это с помощью . grep()
edit: стоит упомянуть, что обе эти функции просто перебираются под капот, между ними не будет заметной разницы в производительности и откатом вашей собственной функции фильтра, но зачем заново изобретать колесо.
Ответ 4
array.forEach(function (elem, i) { // iterate over all elements of array
indexes[elem.id] = i; // take the found id as index for the
}); // indexes array and assign i
результат - это список поиска для id. с данным id мы получаем индекс записи.
Ответ 5
var indices = [];
var IDs = [0, 1, 2, 3, 4];
for(var i = 0, len = array.length; i < len; i++) {
for(var j = 0; j < IDs.length; j++) {
if(array[i].id == ID) indices.push(i);
}
}
Ответ 6
Поскольку нет ответа с использованием регулярного массива find
:
var one = {id: 1, name: 'one'};
var two = {id: 2, name:'two'}
var arr = [one, two]
var found = arr.find((a) => a.id === 2)
found === two // true
arr.indexOf(found) // 1
Ответ 7
Новый способ использования ES6
let picked_element = array.filter(element => element.id === 0);
Ответ 8
Мне кажется, что вы можете создать простой итератор с обратным вызовом для тестирования. Например:
function findElements(array, predicate)
{
var matchingIndices = [];
for(var j = 0; j < array.length; j++)
{
if(predicate(array[j]))
matchingIndices.push(j);
}
return matchingIndices;
}
Затем вы можете вызвать так:
var someArray = [
{ id: 1, text: "Hello" },
{ id: 2, text: "World" },
{ id: 3, text: "Sup" },
{ id: 4, text: "Dawg" }
];
var matchingIndices = findElements(someArray, function(item)
{
return item.id % 2 == 0;
});
// Should have an array of [1, 3] as the indexes that matched
Ответ 9
Адаптация ответа Tejs для mongoDB и Robomongo я изменилась
matchingIndices.push(j);
к
matchingIndices.push(NumberInt(j+1));
Ответ 10
Использование функции ES6 map
:
let idToFind = 3;
let index = someArray.map(obj => obj.id).indexOf(idToFind);
Ответ 11
Подводя итог всему замечательному ответу выше и дополнению моего ответа, касающегося поиска всех индексов из некоторого комментария.
- Чтобы вернуть индекс первого вхождения.
const array = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 2 }];
const idYourAreLookingFor = 2;
//ES5
//Output: 1
array.map(function (x) { return x.id; }).indexOf(idYourAreLookingFor);
//ES6
//Output: 1
array.findIndex(obj => obj.id === idYourAreLookingFor);
Ответ 12
Если вы заботитесь о производительности, не используйте поиск, фильтр, карту или любой из описанных выше методов.
Вот пример, демонстрирующий самый быстрый метод. ЗДЕСЬ ссылка на актуальный тест
Блок настройки
var items = []
for(var i = 0; i < 1000; i++) {
items.push({id: i + 1})
}
var find = 523
Самый быстрый метод
var index = -1
for(var i = 0; i < items.length; i++) {
if(items[i].id === find) {
index = i;
break;
}
}
Более медленные методы
items.findIndex(item => item.id === find)
МЕДЛЕННЫЙ метод
items.map(item => item.id).indexOf(find);
Ответ 13
const index = array.findIndex(item => item.id === 'your-id');
Это должно сделать вам индекс элемента в массиве с id === your-id
array = [ {id:1}, {id:2} ];
const index = array.findIndex(item => item.id === 2);
console.log(index);
Ответ 14
Как я еще не могу прокомментировать, я хочу показать решение, которое я использовал на основе метода Umair Ahmed, но если вы хотите найти ключ вместо значения:
[{"a":true}, {"f":true}, {"g":false}]
.findIndex(function(element){return Object.keys(element)[0] == "g"});
Я понимаю, что он не отвечает на расширенный вопрос, но в заголовке не указывается, что нужно от каждого объекта, поэтому я хочу смиренно поделиться этим, чтобы сохранить головные боли другим в будущем, в то время как я его распаковываю не будет самым быстрым решением.
Ответ 15
Я создал небольшую утилиту под названием super-array, где вы можете получить доступ к элементам в массиве с помощью уникального идентификатора с помощью O (1 ) сложность. Пример:
const SuperArray = require('super-array');
const myArray = new SuperArray([
{id: 'ab1', name: 'John'},
{id: 'ab2', name: 'Peter'},
]);
console.log(myArray.get('ab1')); // {id: 'ab1', name: 'John'}
console.log(myArray.get('ab2')); // {id: 'ab2', name: 'Peter'}
Ответ 16
var test = [
{id:1, test: 1},
{id:2, test: 2},
{id:2, test: 2}
];
var result = test.findIndex(findIndex, '2');
console.log(result);
function findIndex(object) {
return object.id == this;
}
вернет индекс 1 (работает только в ES 2016)
Ответ 17
Мне нравится этот метод, потому что его легко сравнить с любым значением объекта, независимо от того, насколько глубоко оно вложено.
while(i<slides.length && slides[i].props.data!==value){
console.log("data ->", slides[i].props.data, "value",value);
i++;
}
// i now hows the index value for the match.