He estado atascado en este problema durante unos días.
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 }]El objetivo final aquí es que quiero que se fusione en una matriz y los valores se actualicen así:
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 },]
Preferiría mucho más un enfoque Vanilla JS, pero estaré bien con Lodash siempre que acerque el resultado a eso.
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);El código anterior anulará 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}) ) utilizado para restringir la modificación del objeto data2 al modificar final_resultAsí es como lo haría. Como sugirieron los comentarios, ¿qué propiedad se supone que es única? Sería el criterio que usaría para encontrar los datos en la otra matriz, usé la ubicación porque eso es lo único que parecía ser diferente. Por supuesto, puede usar más de una propiedad para encontrar una coincidencia como: 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); }})
Esto sería predeterminado para mantener los datos de la matriz data1 si ambas matrices tienen datos para un objeto. Así que cámbielo por las necesidades de su programa.
Intente usar Array.reduce .
Lógica
data2 con Array.reduce .data1 desde data2 .startingCost y el actualCost .data1 ya se haya cubierto en el resultado. Si eso no está cubierto, empuje el nodo que falta para que resulte. 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);