我已经被这个问题困扰了好几天了
let data1 = [{
project_code: "110",
project_text: "SampleProject1",
location: "Seattle",
startingCost: 0,
actualCost: 399.99
},
{
project: "110",
project_text: "SampleProject1",
location: "Bellevue",
startingCost: 0,
actualCost: 599.99
}];
let data2 = [{
project: "110",
project_text: "SampleProject1",
location: "Seattle",
startingCost: 249.99,
actualCost: ""
},
{
project: "110",
project_text: "SampleProject1",
location: "Bellevue",
startingCost: 699.99,
actualCost: ""
},
{
project: "110",
project_text: "SampleProject1",
location: "North Gate",
startingCost: 899.99,
actualCost: 1199.99
}]
这里的最终目标是我希望它被合并到一个数组中,值应该像这样更新:
let output = [{
project: "110",
project_text: "SampleProject1",
location: "Seattle",
startingCost: 249.99, // FROM DATA2
actualCost: 399.99 // FROM DATA1
},
{
project: "110",
project_text: "SampleProject1",
location: "Bellevue",
startingCost: 699.99, // FROM DATA2
actualCost: 599.99 // FROM DATA1
},
{
// THIS ONE IS ADDING IN NEW DATA
project: "110",
project_text: "SampleProject1",
location: "North Gate",
startingCost: 899.99,
actualCost: 1199.99
},
)
我更喜欢普通的JS方法,但只要我的输出更接近Lodash,我就可以了。
let data1 = [{project_code: "110",project_text: "SampleProject1",location: "Seattle",startingCost: 0,actualCost: 399.99},{project: "110",project_text: "SampleProject1",location: "Bellevue",startingCost: 0,actualCost: 599.99}];
let data2 = [{project: "110",project_text: "SampleProject1",location: "Seattle",startingCost: 249.99,actualCost: ""},{project: "110",project_text: "SampleProject1",location: "Bellevue",startingCost: 699.99,actualCost: ""},{project: "110",project_text: "SampleProject1",location: "North Gate",startingCost: 899.99,actualCost: 1199.99}]
data2.forEach((obj) => {
let ob = data1.find((e) => e.location == obj.location);
// YOU CAN ADD OTHER CONDTIONS HERE WITH && OPERATOR
if (ob !== undefined) {
obj.actualCost = ob.actualCost;
}
});
console.log(data2);
上面的代码将覆盖data2.
let data1 = [{project_code: "110",project_text: "SampleProject1",location: "Seattle",startingCost: 0,actualCost: 399.99},{project: "110",project_text: "SampleProject1",location: "Bellevue",startingCost: 0,actualCost: 599.99}];
let data2 = [{project: "110",project_text: "SampleProject1",location: "Seattle",startingCost: 249.99,actualCost: ""},{project: "110",project_text: "SampleProject1",location: "Bellevue",startingCost: 699.99,actualCost: ""},{project: "110",project_text: "SampleProject1",location: "North Gate",startingCost: 899.99,actualCost: 1199.99}]
var final_result = [];
data2.forEach(({...obj}) => {
let ob = {...data1.find((e) => e.location == obj.location)};
//{...data}; used to Clone Object without reference to do not override data1
if (Object.keys(ob).length !== 0) {
ob.startingCost = obj.startingCost;
final_result.push(ob);
} else {
final_result.push(obj);
}
});
console.log(final_result);
- {…当修改final_result 时,用于限制修改data2对象的forleach (
forEach(({...obj})
)中的obj}。我是这样做的。就像建议的注释一样,哪个属性应该是唯一的?这将是我用来在另一个数组中查找数据的标准,我使用位置,因为这是唯一看起来不同的东西。当然,您可以使用多个属性来查找匹配,例如:item.project === obj.project && item.location === obj.location
data2.forEach(obj=>{
let object1 = data1.find(item=>item.location === obj.location);
if(object1){
object1.startingCost = object1.startingCost || obj.startingCost;
object1.actualCost = object1.actualCost || obj.actualCost;
}
else{
data1.push(obj);
}
})
如果两个数组都有一个对象的数据,则默认保留data1数组中的数据。所以根据你的程序需要改变它。
尝试使用Array.reduce
- 通过
Array.reduce
循环data2
。 - 从
data2
中检查data1
中的匹配节点 - 如果找到匹配的节点,合并
startingCost
和actualCost
。 - 尽管这涵盖了要求,但不要止步于此。您必须验证
data1
中的每个节点已经在结果中被覆盖。如果没有覆盖,则将缺失的节点推入结果。const data1 = [{ project: "110", project_text: "SampleProject1", location: "Seattle", startingCost: 0, actualCost: 399.99 }, { project: "110", project_text: "SampleProject1", location: "Bellevue", startingCost: 0, actualCost: 599.99 }]; const data2 = [{ project: "110", project_text: "SampleProject1", location: "Seattle", startingCost: 249.99, actualCost: "" }, { project: "110", project_text: "SampleProject1", location: "Bellevue", startingCost: 699.99, actualCost: "" }, { project: "110", project_text: "SampleProject1", location: "North Gate", startingCost: 899.99, actualCost: 1199.99 }]; const result = data2.reduce((acc, curr) => { const matchingNode = data1.find((node) => node.project === curr.project && node.project_text === curr.project_text && node.location === curr.location); if(matchingNode) { const updatedNode = { ...matchingNode }; // Take a copy of matching node updatedNode.startingCost = matchingNode.startingCost || curr.startingCost; updatedNode.actualCost = matchingNode.actualCost || curr.actualCost; acc.push(updatedNode); } else { acc.push(curr); } return acc; }, []); // Since we have looped through data2 to generate the array, // we have to ensure that we have not missed any node from data1 aswell data1.forEach((node) => { const matchingNode = result.find((resultNode) => node.project === resultNode.project && node.project_text === resultNode.project_text && node.location === resultNode.location); if (!matchingNode) { result.push(node); } }) console.log(result);