Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

137
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda