首页 > 解决方案 > 比较两个对象数组并用另一个对象替换一个对象

问题描述

我有一个工作函数,将一个对象数组附加customData到另​​一个对象数组的末尾testData。如果具有相同属性name值的对象出现在两个数组中,则该testData对象将被移除并替换customData为结果数组中的对象。该customData对象采用前一个testData对象的顺序。

这是我的尝试,但是我想知道是否有更好的方法来做这件事,而且也很容易阅读(es6)?

谢谢

https://codesandbox.io/s/recursing-river-bdp5k?file=/src/App.js

export default function App() {
  const testData = [
    { display: "1", name: "TEST1" },
    { display: "2", name: "TEST2" }
  ];

  const customData = [
    { display: "CUSTOM_1", name: "TEST1", custom: "YES" },
    { display: "CUSTOM_3", name: "TEST3", custom: "YES" }
  ];

  let i = 0;
  const newTestData = testData;
  let newCustomData = customData;

  while (i < customData.length) {
    const view = customData[i];
    const index = testData.findIndex(x => x.name === view.name);

    if (index >= 0) {
      newTestData[index] = customData[i];
      newCustomData.splice(i, 1);
    }
    i += 1;
  }

  const concatData = newTestData.concat(newCustomData);
  console.log(concatData)

  return null;
}

标签: javascriptecmascript-6

解决方案


Array#concat不会改变数组,无需将它们分配给新变量(无论如何都不会复制数组)。如果您正在寻求使用简洁的 ES6 代码,请跳过 while 循环 - 有许多等价物。这是一个例子:

您没有定义“更好的方式”,但我将其解释为“针对性能和可读性进行了最优化”。在下面的方法中,我使用一次传递来填充地图,另一次传递customData在需要的地方覆盖地图条目,最后是Object.values()(技术上第三次传递)产生结果。这是 O(n) (无嵌套循环)与您的 O(n^2) 实现。

const testData = [
  { display: "1", name: "TEST1" },
  { display: "2", name: "TEST2" }
];

const customData = [
  { display: "CUSTOM_1", name: "TEST1", custom: "YES" },
  { display: "CUSTOM_3", name: "TEST3", custom: "YES" }
];

let map = {};
testData.forEach(item => map[item.name] = item);
customData.forEach(item => map[item.name] = item);
const result = Object.values(map);

console.log(result);

对于包括这种情况在内的许多情况,您有一堆由唯一键(例如name)标识的数据,您确实应该从一开始就使用对象。任何时候你需要一个数组,都有Object.values()and Object.keys()


推荐阅读