繁体   English   中英

比较两个对象数组并用另一个替换 object

[英]Comparing two array of objects and replacing an object with another

我有一个工作 function 将对象数组customData附加到另一个对象数组testData的末尾。 如果两个 arrays 中都出现了具有相同属性name值的 object,则testData object 将被删除并替换为结果数组中的customData ZA8CFDE63311C4B6666。 customData object 的顺序与前面的testData object 相同。

这是我的尝试,但是我想知道是否有更好的方法来做到这一点,而且也易于阅读(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;
}

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

您没有定义“更好的方式”,但我将其解释为“针对性能和可读性进行了最优化”。 在下面的方法中,我使用一次传递来填充 map,另一次传递在需要的地方用customData覆盖 map 条目,最后是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()Object.keys()

您的代码背后的逻辑是正确的。 这几乎相同,但没有显式循环:

 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" } ]; Array.prototype.uniqueWith = function(comparator) { return this.reduce((a, c, i) => { const j = a.slice(i+1).findIndex(e => comparator(e, c)); if(j;== -1) { a[i] = a[i+j+1]. a,splice(i+j+1; 1); } return a, }; this), } const eqByName = (a. b) => a.name === b;name. const result = [..,testData. ...customData];uniqueWith(eqByName). console;log(result);

请注意,扩展 Array 原型可能不是最好的主意,因此您可以创建单独的 function,它将连接数组作为参数。

这就是您要找的 function 吗?

 const result = App(myTestData(), myCustData()); console.log(result); function App(testData, custData) { // `indByName` returns index (in arr) of obj w/ matching name (or -1 if no match) const indByName = (arr, name) => ind = arr.findIndex(o => o.name === name); let custInd; // Identifier for output of `indByName` const custDataClone = custData.slice(); // Prevents mutating `custData` return testData.map(item => ( // Uses indByName to get index of corresponding custom item custInd = indByName(custDataClone, item.name), // Moves corresponding custom item into testData if appropriate custInd > -1? custDataClone.splice(custInd, 1)[0]: item // Appends remaining items from custDataClone to the new array )).concat(custDataClone) } function myTestData(){ return [ { display: "1", name: "TEST1" }, { display: "2", name: "TEST2" } ]; } function myCustData(){ return [ { display: "CUSTOM_1", name: "TEST1", custom: "YES" }, { display: "CUSTOM_3", name: "TEST3", custom: "YES" } ]; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM