Tengo 2 matrices, me gustaría combinarlas si tienen las mismas dos claves de objeto.
Si no se encuentra ninguna coincidencia, mantenga el objeto, pero tenga el valor 0.
Ejemplo de entrada
withdrawal: [ { "id": "a1", "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "withdrawalAmount": 100, "user": "Mike" } { "id": "c3", "withdrawalAmount": 33, "user": "John" } ] deposit: [ { "id": "a1", "depositAmount": 123, "user": "John" }, { "id": "c3", "depositAmount": 44, "user": "John" }, ]Rendimiento esperado
transactions: [ { "id": "a1", "depositAmount": 123, "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "depositAmount": 0, "withdrawalAmount": 100, "user": "Mike" }, { "id": "c3", "depositAmount": 44, "withdrawalAmount": 33 "user": "John" }, ]Esta es la función que probé hasta ahora, pero no funciona debido a que las dos matrices de entrada tienen una longitud diferente.
function mergeArrayObjects(arr1, arr2) { return arr1.map((item, i) => { if (item.user === arr2[i].user) { //merging two objects return Object.assign({}, item, arr2[i]) } }) }Puede lograr el resultado que desea procesando la lista de retiros y depósitos usando Array.reduce a un objeto con los valores de id como claves y los montos de deposit y withdrawal como valores; luego puede tomar los valores de ese objeto para hacer la matriz de transactions :
const withdrawal = [{ "id": "a1", "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "withdrawalAmount": 100, "user": "Mike" } ] const deposit = [{ "id": "a1", "depositAmount": 123, "user": "John" }, { "id": "c3", "depositAmount": 44, "user": "John" } ] const transactions = Object.values( withdrawal .concat(deposit) .reduce((c, { id, depositAmount, withdrawalAmount, ...rest }) => { c[id] = c[id] || {} depositAmount = c[id]['depositAmount'] || depositAmount || 0; withdrawalAmount = c[id]['withdrawalAmount'] || withdrawalAmount || 0; c[id] = ({ id, depositAmount, withdrawalAmount, ...rest }); return c; }, {}) ) console.log(transactions) .as-console-wrapper { max-height: 100% !important; top: 0 } Si desea agrupar tanto por id como por user , debe crear las claves de objeto de resultado a partir de ambos valores, unidos por un carácter que no está en ninguno de ellos (por ejemplo, # funcionaría para sus datos):
const withdrawal = [{ "id": "a1", "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "withdrawalAmount": 100, "user": "Mike" } ] const deposit = [{ "id": "a2", "depositAmount": 123, "user": "John" }, { "id": "b2", "depositAmount": 109, "user": "Mike" }, { "id": "c3", "depositAmount": 44, "user": "John" } ] const transactions = Object.values( withdrawal .concat(deposit) .reduce((c, { id, user, depositAmount, withdrawalAmount, ...rest }) => { key = `${id}#${user}` c[key] = c[key] || {} depositAmount = c[key]['depositAmount'] || depositAmount || 0; withdrawalAmount = c[key]['withdrawalAmount'] || withdrawalAmount || 0; c[key] = ({ id, user, depositAmount, withdrawalAmount, ...rest }); return c; }, {}) ) console.log(transactions) .as-console-wrapper { max-height: 100% !important; top: 0 }A continuación se presenta una posible forma de lograr el objetivo deseado.
Fragmento de código
// helper method to obtain all props // from array-elt matching "id" const getInfo = (ar, argId) => ( ar?.find(({ id }) => id === argId) ?? {} ); // combine both arrays using "id" const combineArrays = (ar1, ar2) => { // first get unique ids combining both arrays const uniqIds = [ ...new Set( [...ar1, ...ar2] .map(({ id }) => id) ) ]; // now, for each unique id // simply get relevant info from both // arrays where element's match the "id" return uniqIds.map(id => ({ id, ...getInfo(ar1, id), ...getInfo(ar2, id) })); }; const withdrawal = [{ "id": "a1", "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "withdrawalAmount": 100, "user": "Mike" } ]; const deposit = [{ "id": "a1", "depositAmount": 123, "user": "John" }]; // invoke the method and display the result console.log( 'combined both arrays as below:\n', combineArrays(withdrawal, deposit) ); .as-console-wrapper { max-height: 100% !important; top: 0 }Explicación
Se agregaron comentarios en línea al fragmento anterior.
const withdrawal = [{ "id": "a1", "withdrawalAmount": 300, "user": "John" }, { "id": "b2", "withdrawalAmount": 100, "user": "Mike" } ] const deposit = [{ "id": "a1", "depositAmount": 123, "user": "John" }, ] const mergeArr = withdrawal.map(ele => { let other = deposit.find(({id}) => id === ele.id) return other ? {...ele, ...other} : {...ele, depositAmount : 0} }) console.log(mergeArr)