Intento como un maníaco hacer algún tipo de combinación / clasificación por clave en una matriz de objetos. No sé por qué, pero no puedo entender cómo hacer eso.
Mi aplicación está en Ionic/Angular.
Esto es lo que tengo:
[ { "2021": { "a": "aText" } }, { "2021": { "b": "bText" } }, { "2020": { "z": "zText" } }, { "2020": { "y": "yText" } }, { "2020": { "x": "xText" } } ]Mi objetivo es conseguir esto:
[ { "2021": { "a": "aText", "b": "bText" } }, { "2020": { "z": "zText", "y": "yText", "x": "xText" } } ]En otras palabras, me gustaría reagruparlos por año y concatarlos.
¿Alguien tiene una idea de cómo hacer eso?
Si solo desea un solo objeto con años como claves, entonces es solo un 'agrupar por' estándar con un bucle anidado para iterar Object.entries() de cada objeto. Si desea su salida publicada originalmente (una matriz de objetos individuales), simplemente puede map() la totalidad del objeto agrupado devuelto y convertir cada uno en un objeto usando Object.fromEntries()
const input = [ { 2021: { a: 'aText' } }, { 2021: { b: 'bText' } }, { 2020: { z: 'zText' } }, { 2020: { y: 'yText' } }, { 2020: { x: 'xText' } }, ]; const grouped_object = input.reduce( (a, o) => (Object.entries(o).forEach(([y, o]) => (a[y] = { ...(a[y] ?? {}), ...o })), a), {} ); // if you just want a single object with years as keys console.log(grouped_object); const grouped_array = Object.entries(grouped_object) .map(([year, data]) => ({[year]: data})); // the output from your question console.log(grouped_array); .as-console-wrapper { max-height: 100% !important; top: 0; } O refactorizado para usar un bucle for...of y Object.assign()
const input = [ { 2021: { a: 'aText' } }, { 2021: { b: 'bText' } }, { 2020: { z: 'zText' } }, { 2020: { y: 'yText' } }, { 2020: { x: 'xText' } }, ]; const grouped_object = {}; for (const obj of input) { for (const [year, data] of Object.entries(obj)) { grouped_object[year] = Object.assign(grouped_object[year] ?? {}, data); } } // if you just want a single object with years as keys console.log(grouped_object); // or avoiding computed properties const grouped_array = Object.entries(grouped_object) .map(([year, data]) => (o={}, o[year]=data, o)); // the output from your question console.log(grouped_array); .as-console-wrapper { max-height: 100% !important; top: 0; }Sería mejor usar un objeto para agrupar por año. Este es un ejemplo que usa reduce para iterar sobre la matriz para producir ese objeto.
const data=[{2021:{a:"aText"}},{2021:{b:"bText"}},{2020:{z:"zText"}},{2020:{y:"yText"}},{2020:{x:"xText"}}]; const out = data.reduce((acc, obj) => { // Get the key and value from the object that in // the current iteration const [ [ key, value ] ] = Object.entries(obj); // If the key doesn't exist on the accumulator (the initial // object that we passed into the `reduce`) create an empty object acc[key] = acc[key] || {}; // Update the value of that object property with // the value of the object acc[key] = { ...acc[key], ...value }; // Return the updated object for the next iteration return acc; // Here's the initial object that // acts as the accumulator through all the iterations }, {}); console.log(out);O usando una matriz para contener la información de cada año:
const data=[{2021:{a:"aText"}},{2021:{b:"bText"}},{2020:{z:"zText"}},{2020:{y:"yText"}},{2020:{x:"xText"}}]; const out = data.reduce((acc, obj) => { const [ [ key, value ] ] = Object.entries(obj); // Use an array instead of an object acc[key] = acc[key] || []; // Push the first element of the Object.values // into the array acc[key] = [ ...acc[key], Object.values(value)[0] ]; return acc; }, {}); console.log(out);Documentación adicional