合并两个没有重复项的数组



我已经被这个问题困扰了好几天了

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);

  1. {…当修改final_result
  2. 时,用于限制修改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中的匹配节点
  • 如果找到匹配的节点,合并startingCostactualCost
  • 尽管这涵盖了要求,但不要止步于此。您必须验证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);

最新更新