【问题标题】:How can I compare two arrays of objects and change a property for those that are not found in another arrays?如何比较两个对象数组并更改在另一个数组中找不到的对象的属性?
【发布时间】:2019-05-02 09:51:00
【问题描述】:

我有 2 个对象数组

var array1 = [{ ID:"1", IsChecked : true}, 
              { ID:"2", IsChecked : true},
              { ID:"3", IsChecked : true},
              { ID:"4", IsChecked : true}]

var array2 = [{ ID:"1", IsChecked : true},
              { ID:"2", IsChecked : true}]

我想比较两个对象数组,并为那些在 array2 中找不到的对象更改 array1(IsChecked : false) 的属性?

这是我预期的结果:

array1 = [{ ID:"1", IsChecked : true}, 
          { ID:"2", IsChecked : true},
          { ID:"3", IsChecked : false},
          { ID:"4", IsChecked : false}]

这是我尝试过的:

array1= new Map(array1.map(o => [o.ID, o]));

array2.forEach(o => map.has(o.ID) && (o.IsChecked= map.get(o.ID).IsChecked == true ? true: false));

但这并没有给出预期的答案

【问题讨论】:

标签: javascript arrays


【解决方案1】:

您可以将地图设为array2,因为您需要使用先前收集的值更新array1 以决定更新。

var array1 = [{ ID: "1", IsChecked: true }, { ID: "2", IsChecked: true }, { ID: "3", IsChecked: true }, { ID: "4", IsChecked: true }],
    array2 = [{ ID: "1", IsChecked: true }, { ID: "2", IsChecked: true }],
    map = new Map(array2.map(({ ID, IsChecked }) => [ID, IsChecked]));

array1.forEach(o => {
    if (map.get(o.ID)) {
        return;
    }
    o.IsChecked = false;
});

console.log(array1);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 一看到问题,我就知道谁会发布答案。干得好@Nina Scholz :)
  • @Nina Scholz:谢谢。甚至我都在期待你的回答。我尝试过的也来自您的旧答案,但稍作修改。 stackoverflow.com/questions/45230436/…
  • 只是一个问题,有必要这么复杂吗? :-)
  • 我想知道我提出的解决方案是否更简单,但我想在时间复杂度较高的情况下,使用地图可能更适合较大的数据集,所以我同意你的看法。 :-)
【解决方案2】:

这对我有用。

var array1 = [
  { ID: "1", IsChecked: true },
  { ID: "2", IsChecked: true },
  { ID: "3", IsChecked: true },
  { ID: "4", IsChecked: true }
];

var array2 = [{ ID: "1", IsChecked: true }, { ID: "2", IsChecked: true }];

array1
  .filter(el => JSON.stringify(array2).indexOf(JSON.stringify(el)) == -1)
  .forEach(el => (el.IsChecked = false));

console.log(array1);

或者,您可以使用

array1
  .filter(el => array2.map(({ID})=>ID).indexOf(el.ID) == -1)
  .forEach(el => (el.IsChecked = false));

【讨论】:

  • 这对数组的每个对象都返回 false
  • 正如我现在检查的那样,您的答案也是正确的,问题是您的答案严格检查两个对象数组中元素的相等性,即,它仅在存在相同数量的元素时才有效在两个对象数组中。但在我的情况下,我有 var array1 = { ID: "1", IsChecked: true, Region:"null" } 和 var array2 = { ID: "1", IsChecked: true },我很抱歉没有提到我的问题中的另一个属性,因为我认为它是可忽略的。再次感谢您。
  • 是的,这就是我提出替代解决方案的原因。这仅检查 ID,因此即使 array2 对每个对象都有 10 个属性,它仍然可以工作。 :-)
  • 是的,我同意@theapologist
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多