Agrupación y Métodos Modernos de Objetos
En el desarrollo con JavaScript frecuentemente necesitamos organizar listas de elementos en grupos según una propiedad (por ejemplo, agrupar productos por categoría o usuarios por rol).
Históricamente esto requería implementar algoritmos manuales con .reduce(). A partir de ES2024, JavaScript incorpora métodos nativos de agrupación: Object.groupBy() y Map.groupBy().
1. Agrupación Nativa con Object.groupBy() (ES2024) #
Object.groupBy(iterable, callback) itera sobre una colección y devuelve un objeto plano con prototipo nulo (null-prototype) cuyas claves son los nombres de grupo devueltos por el callback y cuyos valores son arrays con los elementos agrupados:
1const inventario = [ 2 { nombre: "Manzana", tipo: "Fruta", cantidad: 10 }, 3 { nombre: "Zanahoria", tipo: "Verdura", cantidad: 5 }, 4 { nombre: "Plátano", tipo: "Fruta", cantidad: 20 }, 5 { nombre: "Espinaca", tipo: "Verdura", cantidad: 8 }, 6]; 7 8// Agrupar por tipo de alimento 9const agrupadoPorTipo = Object.groupBy(inventario, item => item.tipo); 10 11console.log(agrupadoPorTipo);Salida de consola { Fruta: [ { nombre: 'Manzana', tipo: 'Fruta', cantidad: 10 }, { nombre: 'Plátano', tipo: 'Fruta', cantidad: 20 } ], Verdura: [ { nombre: 'Zanahoria', tipo: 'Verdura', cantidad: 5 }, { nombre: 'Espinaca', tipo: 'Verdura', cantidad: 8 } ] }
Agrupación por Rangos o Condiciones Dinámicas #
El callback puede devolver cualquier clave calculada:
1const productosStock = Object.groupBy(inventario, item => { 2 return item.cantidad >= 10 ? "stockSuficiente" : "reabastecer"; 3}); 4 5console.log("Para reabastecer:", productosStock.reabastecer.map(p => p.nombre));Salida de consola Para reabastecer: [ 'Zanahoria', 'Espinaca' ]
2. Agrupación con Map.groupBy() #
Si necesitas que las claves de los grupos sean objetos complejos, tipos no string o deseas mantener el orden de inserción estricto, usa Map.groupBy():
1const categoriaVeg = { id: 1, esVegetariano: true }; 2const categoriaNoVeg = { id: 2, esVegetariano: false }; 3 4const platos = [ 5 { plato: "Ensalada", categoria: categoriaVeg }, 6 { plato: "Hamburguesa", categoria: categoriaNoVeg }, 7 { plato: "Gazpacho", categoria: categoriaVeg }, 8]; 9 10const mapaAgrupado = Map.groupBy(platos, p => p.categoria); 11 12console.log("Platos vegetarianos:", mapaAgrupado.get(categoriaVeg).map(p => p.plato));Salida de consola Platos vegetarianos: [ 'Ensalada', 'Gazpacho' ]
3. Transformaciones con Object.fromEntries() y Object.entries() #
Para transformar las propiedades de un objeto usando métodos funcionales de array (map, filter):
1const preciosEuros = { portatil: 1000, raton: 25, teclado: 75 }; 2 3// Aumentar todos los precios un 10% 4const preciosActualizados = Object.fromEntries( 5 Object.entries(preciosEuros).map(([producto, precio]) => [producto, precio * 1.10]) 6); 7 8console.log(preciosActualizados);Salida de consola { portatil: 1100, raton: 27.5, teclado: 82.5 }
Resumen del tema
Conceptos clave #
Object.groupBy()(ES2024): organiza iterables en un objeto plano cuyas propiedades agrupan elementos coincidentes por string/symbol.Map.groupBy()(ES2024): similar aObject.groupBy, pero devuelve una instanciaMap, admitiendo claves de cualquier tipo (incluyendo referencias a objetos).Object.entries()/Object.fromEntries(): par bidireccional para convertir objetos a pares[clave, valor]y reconstruirlos tras aplicar transformaciones funcionales.
Qué debes recordar #
Usa Object.groupBy() para agrupar colecciones de datos de forma nativa, limpia y optimizada sin recurrir a funciones reduce personalizadas.