Как найти удалённые изменённые и добавленные объекты при сравнении старого и нового массива?

Есть такая задача найти удалённые и новые/изменённые (новые и изменённые в одном массиве) объекты в двух массивах из 60 000 объектов. В своём проекте для работы с массивами и объектами я использую библиотеку lodash.

Сейчас я написал код, но время его работы меня смущает, в среднем: 60 - 70 сек

Массивы выглядят примерно вот так, но присутствуют дополнительные ключи, которые тоже должны учитываться:

const newArray = [
  /* id может изменится, а kp_id является уникальным */
  { id: 1, kp_id: 11, name: 'Айнур', age: 19 },
  { id: 2, kp_id: 12, name: 'Занир', age: 21 }, /* изменено */
  { id: 3, kp_id: 13, name: 'Динар', age: 21 },
  { id: 4, kp_id: 14, name: 'Айдар', age: 18 }, /* добавлено */
  ... 60 тыс
]

const oldArray = [
  { id: 1, kp_id: 11, name: 'Айнур', age: 19 },
  { id: 2, kp_id: 12, name: 'Занир', age: 20 },
  { id: 3, kp_id: 13, name: 'Динар', age: 21 },
  ... 60 тыс
]

Вот так я нахожу изменённые и добавленные объекты:

const updated = newArray.filter(newObject => {
  const oldObject == oldArray.find(o => o.kp_id == newObject.kp_id)
  return !lodash.idEqual(newObject, oldObject)
})

А вот так я нахожу удалённые объекты:

const deleted = oldArray.filter(oldObject => {
  const newObject = newArray.find(o => o.kp_id == oldObject.kp_id)
  return !lodash.isEqual(newobject, oldobject)
}).pullAllBy(updated, 'kp_id').value()

Есть идеи, какой новый подход можно применить? Буду рад любой помощи.


Ответы (1 шт):

Автор решения: nörbörnën

Попробуйте так:

import { isDeepStrictEqual } from 'node:util';

const newArray = [
  { id: 1, kp_id: 11, name: 'Айнур', age: 19 },
  { id: 2, kp_id: 12, name: 'Занир', age: 21 },
  { id: 3, kp_id: 13, name: 'Динар', age: 21 },
  { id: 4, kp_id: 14, name: 'Айдар', age: 18 },
];

const oldArray = [
  { id: 1, kp_id: 11, name: 'Айнур', age: 19 },
  { id: 2, kp_id: 12, name: 'Занир', age: 20 },
  { id: 3, kp_id: 13, name: 'Динар', age: 21 },
  { id: 3, kp_id: 130, name: 'Rick Sanches', age: 75 },
];

const newArrayMap = new Map(newArray.map((x) => [x.kp_id, x]));
const oldArrayMap = new Map(oldArray.map((x) => [x.kp_id, x]));

newArray.forEach((x) => {
  if (oldArrayMap.has(x.kp_id)) {
    if (!isDeepStrictEqual(x, oldArrayMap.get(x.kp_id))) {
      console.log(`изменено: ${JSON.stringify(x)}`);
    }
  } else {
    console.log(`добавлено: ${JSON.stringify(x)}`);
  }
});

oldArray.forEach((x) => {
  if (!newArrayMap.has(x.kp_id)) {
    console.log(`удалено: ${JSON.stringify(x)}`);
  }
});

Результат:

~/tmp/q $ node found-changed.js 
изменено: {"id":2,"kp_id":12,"name":"Занир","age":21}
добавлено: {"id":4,"kp_id":14,"name":"Айдар","age":18}
удалено: {"id":3,"kp_id":130,"name":"Rick Sanches","age":75}
→ Ссылка