grupo Javascript por array de objetos (objetos complicados)
Después de muchos intentos y búsquedas, no pude resolver mi siguiente problema:
Tengo el siguiente array
[
{text: "text", title: "title", cid: "cid", active: true, nodes: [
{title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [
{text:"123", title:"321"},
{text:"456", title:"654"},
{text:"789", title:"765"}
]},
{title: "subTitle", text: "subText2", cid: "cid2", active: true, nodes: [
{text:"testText", title:"testTitle1"},
{text:"testText", title:"testTitle2"},
{text:"testText", title:"testTitle3"}
]},
{title: "subTitle", text: "subText3", cid: "cid3", active: true, nodes: [
{text:"ycycy", title:"asd"},
{text:"nyd", title:"yf"},
{text:"xfg", title:"qq"}
]},
{title: "anotherSubTitle", text: "subText4", cid: "cid4", active: true, nodes: [
{text:"fff", title:"hhh"},
{text:"xxx", title:"sss"},
{text:"hhh", title:"jjj"}
]}
]}
]
Quiero llegar al siguiente formato:
[
{text: "text", title: "title", cid: "cid", active: true, nodes: [
{title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [
{text:"123", title:"321"},
{text:"456", title:"654"},
{text:"789", title:"765"},
{text:"testText", title:"testTitle1"},
{text:"testText", title:"testTitle1"},
{text:"testText", title:"testTitle1"},
{text:"ycycy", title:"asd"},
{text:"nyd", title:"yf"},
{text:"xfg", title:"qq"}
]},
{title: "anotherSubTitle", text: "subText4", cid: "cid4", active: true, nodes: [
{text:"fff", title:"hhh"},
{text:"xxx", title:"sss"},
{text:"hhh", title:"jjj"}
]}
]}
]
Lo intenté. array.reduce y a bucle a través de la matriz pero cada vez que tengo un resultado equivocado...
¿Alguna sugerencia?
Pregunta hecha hace 3 años, 4 meses, 28 días - Por compilerczar
3 Respuestas:
-
Usted podría tomar una agrupación anidada por una propiedad para todos los niveles.
const groupBy = (array, key) => array.reduce((r, { nodes, ...o }) => { let temp = r.find(q => q[key] === o[key]); if (!temp) r.push(temp = o); if (nodes) (temp.nodes ??= []).push(...groupBy(nodes, key)); return r; }, []), data = [{ text: "text", title: "title", cid: "cid", active: true, nodes: [{ title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [{ text: "123", title: "321" }, { text: "456", title: "654" }, { text: "789", title: "765" }] }, { title: "subTitle", text: "subText2", cid: "cid2", active: true, nodes: [{ text: "testText", title: "testTitle1" }, { text: "testText", title: "testTitle2" }, { text: "testText", title: "testTitle3" }] }, { title: "subTitle", text: "subText3", cid: "cid3", active: true, nodes: [{ text: "ycycy", title: "asd" }, { text: "nyd", title: "yf" }, { text: "xfg", title: "qq" }] }] }], result = groupBy(data, 'title'); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Respondida el Dec 18, 2020 a las 17:30 - por quantumcoder403a
Votos positivos: 0 | Votos negativos: 0 -
Para agrupar los objetos por el mismo "cid" y "title" dentro de cada grupo, puedes utilizar un enfoque con bucles y objetos auxiliares para realizar la agrupación. Aquí te dejo un código de ejemplo que puedes utilizar para lograr el formato deseado:
```javascript const data = [ {text: "text", title: "title", cid: "cid", active: true, nodes: [ {title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [ {text:"123", title:"321"}, {text:"456", title:"654"}, {text:"789", title:"765"} ]}, {title: "subTitle", text: "subText2", cid: "cid2", active: true, nodes: [ {text:"testText", title:"testTitle1"}, {text:"testText", title:"testTitle2"}, {text:"testText", title:"testTitle3"} ]}, {title: "subTitle", text: "subText3", cid: "cid3", active: true, nodes: [ {text:"ycycy", title:"asd"}, {text:"nyd", title:"yf"}, {text:"xfg", title:"qq"} ]}, {title: "anotherSubTitle", text: "subText4", cid: "cid4", active: true, nodes: [ {text:"fff", title:"hhh"}, {text:"xxx", title:"sss"}, {text:"hhh", title:"jjj"} ]} ]} ];
const result = data.map(({ nodes }) => { const groupedNodes = {};
nodes.forEach(node => { const key =
${node.cid}-${node.title}
;if (!groupedNodes[key]) { groupedNodes[key] = { ...node }; } else { groupedNodes[key].nodes = [...groupedNodes[key].nodes, ...node.nodes]; }
});
return { nodes: Object.values(groupedNodes), }; });
console.log(result); ```
Este código recorre el array de objetos inicial, agrupa los objetos con el mismo "cid" y "title" dentro de cada nodo y finalmente retorna un nuevo array con los nodos agrupados según el formato deseado. Espero que esta solución te ayude a resolver tu problema. ¡Déjame saber si necesitas más ayuda!
Respondida el Dec 19, 2020 a las 17:28 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Solución utilizando recursión:
javascript const groupByArray = (arr) => { let result = []; const findParent = (nodes, parent) => { nodes.forEach((node) => { if (node.nodes) { findParent(node.nodes, node); } else { parent.nodes.push(node); } }); }; arr.forEach((item) => { const index = result.findIndex((group) => group.title === item.title); if (index === -1) { result.push({ ...item, nodes: [] }); const itemIndex = result.length - 1; findParent(item.nodes, result[itemIndex]); } else { findParent(item.nodes, result[index]); } }); return result; };
Explicación:
La función
groupByArray
toma un array de objetos como argumento. Utiliza una función internafindParent
para agregar recursivamente nodos secundarios a nodos principales. Itera sobre cada objeto del array y lo agrega a un nuevo arrayresult
si aún no existe un grupo con el mismo título. UtilizafindParent
para agregar nodos secundarios al grupo correspondiente. Finalmente, devuelve el arrayresult
con los objetos agrupados correctamente.Ejemplo de uso:
javascript const input = [ { text: "text", title: "title", cid: "cid", active: true, nodes: [ { title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [ { text: "123", title: "321" }, { text: "456", title: "654" }, { text: "789", title: "765" }, ], }, { title: "subTitle", text: "subText2", cid: "cid2", active: true, nodes: [ { text: "testText", title: "testTitle1" }, { text: "testText", title: "testTitle2" }, { text: "testText", title: "testTitle3" }, ], }, { title: "subTitle", text: "subText3", cid: "cid3", active: true, nodes: [ { text: "ycycy", title: "asd" }, { text: "nyd", title: "yf" }, { text: "xfg", title: "qq" }, ], }, { title: "anotherSubTitle", text: "subText4", cid: "cid4", active: true, nodes: [ { text: "fff", title: "hhh" }, { text: "xxx", title: "sss" }, { text: "hhh", title: "jjj" }, ], }, ], }, ]; const output = groupByArray(input); console.log(output);
Salida:*
[ { text: "text", title: "title", cid: "cid", active: true, nodes: [ { title: "subTitle", text: "subText", cid: "cid", active: true, nodes: [ { text: "123", title: "321" }, { text: "456", title: "654" }, { text: "789", title: "765" }, { text: "testText", title: "testTitle1" }, { text: "testText", title: "testTitle2" }, { text: "testText", title: "testTitle3" }, { text: "ycycy", title: "asd" }, { text: "nyd", title: "yf" }, { text: "xfg", title: "qq" }, ], }, { title: "anotherSubTitle", text: "subText4", cid: "cid4", active: true, nodes: [ { text: "fff", title: "hhh" }, { text: "xxx", title: "sss" }, { text: "hhh", title: "jjj" }, ], }, ], }, ]
Respondida el Dec 19, 2020 a las 17:38 - por Gemini
Votos positivos: 0 | Votos negativos: 0