Сравнение массива для каждой проблемы производительности - PullRequest
0 голосов
/ 03 мая 2019

У меня есть два массива с массивом объектов, как показано ниже, и один массив будет иметь более 10 тыс. Записей, а другой - менее 100 записей

let bigArray = [{id:1, name:"Raj", level:0}, {id:2, name:"sushama", level:2}, {id:3, name:"Sushant", level:0}, {id:4, name:"Bhaskar", level:2},....upto 30k records] 

let smallArray = [{id:2, name:"sushama"}, {id:3, name:"Sushant"}....upto 100 records] 

Я хочу найти, где в индексе bigArray находится объект из smallArray, и добавить в другой массив сказать indexArray, который я пробовал ниже

let indexArray = []; 
bigArray.forEach((element, i) => {
  smallArray.forEach(ele => {
    if (element.name == ele.name && element.id == ele.id) {
      indexArray.push(i); return;
    } 
  }); 
}); 

Но это требует времени. Какой будет самый быстрый подход?

Ответы [ 3 ]

4 голосов
/ 03 мая 2019

Вы можете превратить ваш подход O(N^2) в подход O(N), уменьшив bigArray до объекта, индексированного ключом, составленным из name и id.Соедините name и id с помощью символа, который не содержится ни в одном, например, _:

const indexArray = [];
const bigArrayIndiciesByNameAndId = bigArray.reduce((a, { name, id }, i) => {
  a[name + '_' + id] = i;
  return a;
}, {});

smallArray.forEach(ele => {
  const keyToFind = ele.name + '_' + ele.id;
  const foundIndex = bigArrayIndiciesByNameAndId[keyToFind];
  if (foundIndex) {
    indexArray.push(foundIndex);
  }
});
2 голосов
/ 03 мая 2019

return не «разорвет» петлю forEach.A forEach не может быть остановлено.Функция обратного вызова forEach будет вызываться один раз для каждого элемента всегда.Когда вы найдете элемент, продолжайте выполнение цикла forEach - это пустая трата ресурсов.

Вместо этого следует использовать for:

let indexArray = []; 
bigArray.forEach((element, i) => {
    for (var ii = 0; ii < smallArray.length; ii++) {
        var ele = smallArray[ii];
        if (element.name == ele.name && element.id == ele.id) {
            indexArray.push(i);
            break; // This will break the "for" loop as we found the item
        }
    }
});

СОВЕТ: Всегда иметь хороший отступ вваш код.На самом деле ваш код имеет плохие отступы для идентификации блоков кода с первого взгляда.Я исправил это в этом примере.

2 голосов
/ 03 мая 2019

Вы можете взять Map и отобразить найденные индексы.

const getKey = ({ id, name }) => [id, name].join('|');

let bigArray = [{ id: 1, name: "Raj", level: 0 }, { id: 2, name: "sushama", level: 2 }, { id: 3, name: "Sushant", level: 0 }, { id: 4, name: "Bhaskar", level: 2 }],
    smallArray = [{ id: 2, name: "sushama" }, { id: 3, name: "Sushant" }],
    map = new Map(bigArray.map((o, i) => [getKey(o), i]))
    indexArray = smallArray.map((o) => map.get(getKey(o)));

console.log(indexArray);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...