Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

136
Views
Combinar 2 matrices de objetos pero combinar matrices si las propiedades tienen el mismo valor

Tengo dos objetos con la siguiente estructura:

 let sourceObj = [ { items: [ { items: [{ id: '0', name: 'z' }], name: 'm' }, { items: [{ id: '2', name: 'q' }], name: 'l' }, ], name: 'c' }, { items: [ { items: [{ id: '4', name: '-' }], name: 'v' }, ], name: 'd' } ]; let targetObj = [ { items: [ { items: [{ id: '1', name: 'd' }], name: 'm' }, { items: [{ id: '3', name: 'b' }], name: 'j' }, ], name: 'c' } ];

Quiero fusionar este objeto para obtener un objeto con la siguiente estructura:

 let merged = [ { items: [ { items: [ { id: '0', name: 'd' }, { id: '1', name: 'z' }], name: 'm' }, { items: [{ id: '2', name: 'q' }], name: 'l' }, { items: [{ id: '3', name: 'b' }], name: 'j' }, ], name: 'c' }, { items: [ { items: [{ id: '4', name: '-' }], name: 'v' }, ], name: 'd' } ]

Es decir, quiero obtener el objeto, que se ha unido a las matrices si el nombre de la matriz de origen es el mismo en la matriz de destino.

Intenté usar el método lodash mergeWith, pero solo pude unir elementos de nivel superior de colecciones ...

 mergeWith(sourceObj, targetObj, (objValue, srcValue) => { if (isArray(objValue)) { return objValue.concat(srcValue); } });
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Tiene razón en que el mergeWith de mergeWith no se fusiona recursivamente. Puede administrar esto usted mismo manualmente.

  1. Primero itere la primera matriz y genere un objeto de mapa por la propiedad de name .
  2. Luego itere la segunda matriz y verifique si la propiedad del name coincide, y si es así, llame recursivamente a la función de merge para combinar las dos matrices anidadas de las matrices de origen y destino, de lo contrario, agregue el elemento de la segunda matriz al mapa de objetos.
  3. Finalmente, vuelva a convertir el objeto de mapa en una matriz de los valores combinados.

Código:

 const merge = (sourceArr, targetArr) => { // (1) generate lookup map const objMap = sourceArr.reduce((map, curr) => { return { ...map, [curr.name]: curr }; }, {}); // (2) Merge objects, recurse on items arrays targetArr.forEach((obj) => { if (objMap[obj.name]) { objMap[obj.name].items = merge(objMap[obj.name].items, obj.items); } else { objMap[obj.name] = obj; } }); // (3) Return merged values array return Object.values(objMap); }; 

 const sourceObj = [ { items: [ { items: [{ id: "0", name: "z" }], name: "m" }, { items: [{ id: "2", name: "q" }], name: "l" } ], name: "c" }, { items: [{ items: [{ id: "4", name: "-" }], name: "v" }], name: "d" } ]; const targetObj = [ { items: [ { items: [{ id: "1", name: "d" }], name: "m" }, { items: [{ id: "3", name: "b" }], name: "j" } ], name: "c" } ]; const merge = (sourceArr, targetArr) => { const objMap = sourceArr.reduce((map, curr) => { return { ...map, [curr.name]: curr }; }, {}); targetArr.forEach((obj) => { if (objMap[obj.name]) { objMap[obj.name].items = merge(objMap[obj.name].items, obj.items); } else { objMap[obj.name] = obj; } }); return Object.values(objMap); }; const res = merge(sourceObj, targetObj); console.log(res);

about 4 years ago · Juan Pablo Isaza Report

0

Encuentro que una dosis de recursividad mutua hace que el código sea más limpio aquí.

 const combineItems = (o = {}, items) => o .items || items .length ? {items: deepMerge (o.items || [], items)} : {} const deepMerge = (xs, ys) => Object .values ([... xs, ... ys] .reduce ( (a, {name, items = [], ...rest}) => ({ ... a, [name]: { ... (a [name] || {name, ...rest}), ... combineItems (a [name], items) } }), {} )) const sourceObj = [{items: [{items: [{id: "0", name: "z"}], name: "m"}, {items: [{id: "2", name: "q"}], name: "l"}], name: "c"}, {items: [{items: [{id: "4", name: "-"}], name: "v"}], name: "d"}] const targetObj = [{items: [{items: [{id: "1", name: "d"}], name: "m"}, {items: [{id: "3", name: "b"}], name: "j"}], name: "c"}]; console .log (deepMerge (sourceObj, targetObj))
 .as-console-wrapper {max-height: 100% !important; top: 0}

deepMerge es la función principal, pero delega a combineItems para manejar las diversas combinaciones de si ya tenemos elementos para combinar o no. combineItems devolverá algo como {items: [<item1>. <item2>, ...]} o simplemente {} , dependiendo de si se han encontrado elementos.

Hay un problema de rendimiento potencial aquí, que Rich Snapp ha denominado The reduce ({...spread}) anti-pattern . Personalmente, no me preocuparía aquí si el código funciona a su satisfacción. Pero si no, podemos cambiarlo para que coincida con sus sugerencias, a algo como esto:

 const deepMerge = (xs, ys) => Object .values ([... xs, ... ys] .reduce ( (a, {name, items = [], ...rest}) => { const x = a [name] || {name, ...rest} if (items.length || x.items) x .items = deepMerge (x .items || [], items) a [name] = x return a }, {} ))
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!