匹配对象数组中的对象并删除

match an object in an array of objects and remove

经过 2 天的努力解决这个问题,我希望有人能帮助我。

我有两个对象数组,如下所示:

let oldRecords = [
  {name: 'john'},
  {name: 'ringo'}
];

let newRecords = [
  {name: 'paul'},
  {name: 'john'},
  {name: 'stuart'}
];

我试图以一个 returns 命名变量的函数结束,其中包含已添加的数据列表(存在于 newRecords 但不存在于 oldRecords 中)和一个列表已删除的数据(存在于 oldRecords 但不存在于 newRecords 中)。

例如

const analyse = (older, newer) => {
  let added, removed;
    // ... magic
  return {added, removed}
}

const {added, removed} = analyse(oldRecords, newRecords);

我不会post我在这个函数中尝试过的所有代码,因为我试图映射、减少和循环两个数组,在过去的 48 小时内创建临时数组,我现在可以填充一本包含我编写和删除的代码的书。我还使用了 underscore.js 方法,例如 reject/find/findWhere 这些方法都让我接近但没有雪茄。

我遇到的主要问题是因为数组包含对象,如果它们包含数字则非常容易,即

var oldRecords = [1, 3];
var newRecords = [1, 2, 4]

function analyse (old, newer) { 
  let added = [];
  let removed = [];

  old.reduce((o) => {
    added = added.concat(_.reject(newer, (num) => num === o ));
  });

  newer.reduce((n) => {
    removed = _.reject(old, (num) => num === n );
  });

  return {added, removed}
}

const {added, removed} = analyse(oldRecords, newRecords);

如何使用对象而不是数组实现上述目标?

n.b。我尝试修改上面的内容并使用 JSON.stringify 但它并没有真正起作用。

编辑:重要的一点我忘了补充,对象结构及其 keys 是动态的,它们来自数据库,所以任何单独检查 key 也必须是动态的,即不是硬编码值

您可以使用 reject and some to check for inclusion in the appropriate sets. The isEqual 函数来检查是否相等以处理动态键:

const analyse = (older, newer) => {
  let added = _.reject(newer, n => _.some(older, o =>_.isEqual(n, o)));
  let removed = _.reject(older, o => _.some(newer, n => _.isEqual(n, o)));

  return {added, removed}
}

你可以试试这个:

const analyse = (older, newer) => {
   let removed = older.filter(newItem => {
     return newer.filter(oldItem => {
        return _.isEqual(newItem, oldItem);
     }).length === 0
   });

   let added = newer.filter(oldItem => {
     return older.filter(newItem => {
        return _.isEqual(newItem, oldItem);
     }).length === 0
   });

   return {added, removed};
}

您可以先创建函数来检查两个对象是否相等,然后使用 filter()some() 得到 return 结果。

let oldRecords = [
  {name: 'john'},
  {name: 'ringo'}
];

let newRecords = [
  {name: 'paul'},
  {name: 'john'},
  {name: 'stuart'}
];


function isEqual(o1, o2) {
  return Object.keys(o1).length == Object.keys(o2).length &&
    Object.keys(o1).every(function(key) {
      return o2.hasOwnProperty(key) && o1[key] == o2[key]
    })
}

var result = {}
result.removed = oldRecords.filter(e => !newRecords.some(a => isEqual(e, a)))
result.added = newRecords.filter(e => !oldRecords.some(a => isEqual(e, a)))
console.log(result)