[英]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.