Reputation: 119
I've been stuck on this problem for a few days now.
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
}]
The end goal here is that i want it to be merged into one array and the values should be updated like this:
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
},
]
I would much prefer a vanilla JS approach but i'll be ok with Lodash as long as i get the output closer to that.
Upvotes: 1
Views: 195
Reputation: 19986
Try using Array.reduce
.
Logic
data2
with Array.reduce
.data1
from data2
.startingCost
and actualCost
.data1
has already been covered in result. If that is not covered, push the missing node to result.
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);
Upvotes: 0
Reputation: 1139
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);
The above code will override 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);
forEach(({...obj})
) used to restrict modifying data2 object when modifying final_resultUpvotes: 2
Reputation: 63
This is how I would do it. Like the comments suggested, which property is suppose to be unique? It would be the criteria I would use to find the data in the other array, I used location because that is the only thing that seemed to be different. You can of course use more than one property to find a match like:
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);
}
})
This would default to keeping the data from data1 array if both arrays have data for an object. So change it around for what your program needs are.
Upvotes: 0