我有一个工作函数,可将对象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;
}
答案 0 :(得分:0)
Array#concat
不会使数组发生突变,因此无需将它们分配给新变量(无论如何也不会复制数组)。如果您想使用简洁的ES6代码,请跳过while循环-有许多等效项。这是一个示例:
您没有定义“更好的方式”,但我将其解释为“针对性能和可读性进行了最优化”。在下面的方法中,我使用一个步骤填充地图,然后使用另一遍在需要时用customData
覆盖地图条目,最后使用Object.values()
(技术上是第三遍)来生成结果。与您的O(n ^ 2)实现相比,这是O(n)(无嵌套循环)。
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()
。
答案 1 :(得分:0)
代码背后的逻辑是正确的。 这几乎是相同的,但是没有显式循环:
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原型可能不是最好的主意,因此您可以创建单独的函数,该函数将级联数组作为参数。
答案 2 :(得分:0)
这是您要寻找的功能吗?
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" }
];
}