He intentado varias respuestas a esta pregunta (igual/similar) aquí, y ninguna ha dado el resultado deseado. Tengo un archivo Json plano que necesito convertir a anidado. El primer elemento de cada fragmento es el elemento en el que se deben agrupar los datos cuando se convierten en datos anidados. Los datos de ejemplo solo muestran dos "tipos", pero hay varios más en los datos, y también algunos otros elementos junto con el color y el tamaño; lo mantuve breve para publicar aquí.
Ejemplo de entrada de datos:
[ { "type": "Background", "colour": "Blue", "size": "5" }, { "type": "Background", "colour": "Grey", "size": "3" }, { "type": "Foreground", "colour": "Red", "size": "5" }, { "type": "Foreground", "colour": "White", "size": "10" } ]
Salida deseada:
[ { "type": "Background", "elements": [ { "colour": "Blue", "size": "5" }, { "colour": "Grey", "size": "3" } ] } { "type": "Foreground", "elements": [ { "colour": "Red", "size": "5" }, { "colour": "White", "size": "10" } ] } ]
Lo más cerca que llegué a una respuesta para esto fue aquí: Crear json anidado a partir de JSON aplanado en javascript
Pero el resultado que recibí de eso (en VSCode) fue este:
{ type: { elements: [ [Object], [Object] ] } }
Mientras trato de seguir el código, está más allá de mi conocimiento de JavaScript actualmente, por lo que no sé qué está mal o por qué obtengo [objeto] y no los elementos reales.
¿Alguien puede ayudarme a resolver esto para que mi salida se vea como mi "Salida deseada" anterior?
¡Salud!
Puede usar el método forEach()
para recorrer la matriz, en este caso, result . Si el tipo no se configuró en el resultado , agregue el nuevo tipo. Pero, si el elemento ya tiene su tipo en el resultado , simplemente presione los elementos del elemento.
const items = [ { type: 'Background', colour: 'Blue', size: '5', }, { type: 'Background', colour: 'Grey', size: '3', }, { type: 'Foreground', colour: 'Red', size: '5', }, { type: 'Foreground', colour: 'White', size: '10', }, ]; let result = []; items.forEach((item) => { if (!result.find((x) => x.type === item.type)) { result.push({ type: item.type, elements: [] }); } result .find((x) => x.type === item.type) .elements.push({ color: item.colour, size: item.size, }); }); console.log(result);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
prueba esto
var output = []; var newObj = { type: input[0].type, elements: [] }; var prevType = input[0].type; input.forEach((element) => { if (element.type != prevType) { output.push(newObj); newObj = { type: element.type, elements: [] }; prevType = element.type; } newObj.elements.push({ colour: element.colour, size: element.size }); }); output.push(newObj);
Parece que hay dos pasos aquí. Primero agrupe todas las entradas con el mismo tipo (lo que sería más fácil bajo el nombre del tipo como una propiedad), luego cree el anidamiento.
const input = [ { "type": "Background", "colour": "Blue", "size": "5" }, { "type": "Background", "colour": "Grey", "size": "3" }, { "type": "Foreground", "colour": "Red", "size": "5" }, { "type": "Foreground", "colour": "White", "size": "10" } ]; var assist = {}, output = []; // Group original objects based on type // The type is used as a property value for (let i = 0; i < input.length; i++) { let type = input[i].type; if (assist.hasOwnProperty(type)) { assist[type].push(input[i]); } else { assist[type] = [input[i]]; } delete input[i].type; } // Turn the grouped entries into new array entries let keys = Object.keys(assist); for (let i = 0; i < keys.length; i++) { output.push({ type: keys[i], elements: assist[keys[i]] }); }; // Show results console.log(output);
Tenga en cuenta que si bien el código anterior no modifica la matriz original, modifica sus miembros (eliminando su propiedad de type
) y usándolos en la matriz de salida. Tendrás que clonarlo si también necesitas el original.