#arrays #json #jsonobjectrequest #json-arrayagg
Вопрос:
Я хочу знать лучший способ получения индексов из огромного (длина массива почти 150 000) массива JSON объектов JSON, который совпадает с массивом объектов JSON.
В настоящее время я использую цикл for для выполнения этой работы, но это занимает от 3 до 4 минут времени. Есть ли какой-нибудь лучший способ улучшить производительность? Ниже приведен пример, иллюстрирующий мое требование.
var hugeArray = [
{firstName:"John", lastName:"Doe", age:21},
{firstName:"Abraham", lastName:"Lincoln", age:46},
{firstName:"Andy", lastName:"Crossland", age:32},
.
.
.
{firstName:"Jimmy", lastName:"Fletcher", age:65}
];
Предположим, что длина огромного массива составляет 150 000. И у меня есть еще один массив JSON(matchArray) длиной 15 000.
var matchArray = [
{firstName:"John", lastName:"Doe"},
{firstName:"Andy", lastName:"Crossland"},
.
.
.
{firstName:"Jimmy", lastName:"Fletcher"}
];
Мне нужны индексы из hugeArray, которые совпадают с matchArray.
Например, из приведенных выше данных, в matchArray есть список объектов, и эти объекты должны быть сопоставлены с объектами в массиве. Если совпадет, то верните индексы hugeArray. Результат приведенного выше примера будет таким, как показано ниже.
[0,2,...,150000]
Для этого я написал функцию, и эта функция возвращает индекс hugeArray. Если объект matchArray совпадает с hugeArray, то возвращает индекс совпадающего hugeArray, в противном случае возвращает -1.
//returns -1 if no matched objects found otherwise returns index of searchArray that matched with obj.
//searchArray : Array that used to search in and return matched index.
//obj : JSON object which is used to match in with searchArray objects.
function getArrayIndex(searchArray,obj){
var index = -1;
for(var i=0,searchArrayLen=searchArray.length;i<searchArrayLen;i ){
var keyMatch = true;
for(var key in obj){
if(obj[key].trim() !== searchArray[i][key].trim()){
keyMatch = false;
break;
}
}
if(keyMatch){
index = i;
return index;
}
}
return index;
}
Написал ниже функцию getIndexes, чтобы вызвать выше функцию getArrayIndex.
//returns array of indexes.
function getIndexes(hugeArray,matchArray){
var indexArray = [];
var matchArrayLen = matchArray.length;
for(var i=0; i<matchArrayLen; i ){
var matchIndex = getArrayIndex(hugeArray,matchArray[i]);
if(matchIndex !== -1){
indexArray.push(matchIndex);
}
}
return indexArray;
}
Наконец, вызвав функцию getIndexes, предоставив все совпадающие индексы в формате массива.
Например,
var index = getIndexes(hugeArray,matchArray);
console.log(index);// This prints an array that contains matched indexes.
//For above data, output will be like [0,2,...,150000].
Комментарии:
1. Пожалуйста, не используйте здесь индийские слова, такие как лакх / лак. Люди, живущие в другом месте, не поймут их.
2. @JamesZ Хорошо, спасибо, что дали мне знать и исправили вопрос.
Ответ №1:
Для этого можно использовать объект карты.
let theMap = new Map(hugeArray.map((item, index) => [item.firstName " " item.lastName, index]));
let result = matchArray.map(item => theMap.get(item.firstName " " item.lastName))
.filter(i => i !== undefined)
Это предполагает firstName
наличие или lastName
отсутствие пробелов. Используйте другой символ, если они могут содержать пробелы.
Если hugeArray
есть дубликаты:
let theMap = new Map();
hugeArray.forEach((item, index) => {
let key = item.firstName " " item.lastName;
let value = theMap.get(key);
if (value === undefined)
theMap.set(key, [index]);
else
value.push(index);
});
let result = matchArray.flatMap(item => theMap.get(item.firstName " " item.lastName))
.filter(i => i !== undefined);
Если нам нужен отсортированный результат, когда hugeArray
есть дубликаты:
let result = matchArray.flatMap(item => theMap.get(item.firstName " " item.lastName))
.filter(i => i !== undefined).sort();
Комментарии:
1. Потрясающе, спасибо за ответ. Твое решение сделало мой день лучше!. Отлично работает. Теперь работа выполнена за 3 секунды, в то время как это было 3-4 минуты назад.
2. решение работает для уникального совпадения, а не для дубликатов. Допустим, что делать, если hugeArray имеет дубликаты и сопоставлен с matchArray ? Мне нужны все индексы из hugeArray, которые совпадают, но приведенное выше решение дает только первое совпадение с последним индексом.
3. Снова потрясающе 🙂 Работает идеально ! Трудно это понять
else condition
. Не могли бы вы, пожалуйста, объяснить, как настроить объект карты для hugeArray ? То, что я заметил, таково… при установке в объект карты мы выполняем проверку дубликатов. Если найден дубликат, вставьте только индекс в существующий элемент объекта карты, в противном случае вставьте в объект карты как новую запись.4. @user2388677 Для каждого ключа мы помещаем массив на карту. В этой
if
части мы помещаем массив размером 1 (с индексом в качестве единственного элемента) на карту для первого появления ключа. В этойelse
части мы добавляем текущий индекс в конец указанного массива для второго и следующих вхождений ключа.