¿Cómo puedo agrupar esta matriz de objetos por categoria ?
items = [ { categoria: 'Sandwiches', nombre: 'Sandwich de Pollo', precio: 12 }, { categoria: 'Sandwiches', nombre: 'Sandwich de Lomo', precio: 12 }, { categoria: 'Helados', nombre: 'Helado de 1 bola', precio: 5 }, { categoria: 'Helados', nombre: 'Helado de 2 bolas', precio: 8 }, { categoria: 'Helados', nombre: 'Helado de 3 bolas', precio: 10 }, ];Quiero obtener algo como esto, estoy trabajando en Typescript con Angular:
itemsResult = [ { categoria: 'Sandwiches', items: [ { nombre: 'Sandwich de Pollo', precio: 12 }, { nombre: 'Sandwich de Lomo', precio: 12 }, ] }, { categoria: 'Helados', items: [ { nombre: 'Helado de 1 bola', precio: 5 }, { nombre: 'Helado de 2 bolas', precio: 8 }, { nombre: 'Helado de 3 bolas', precio: 10 }, ] }, ]; Lo he intentado con un reduce pero lo que obtengo es un objeto, quiero una matriz
this.itemsGroup = this.items.reduce((r, a) => { r[a.categoria] = r[a.categoria] || []; r[a.categoria].push(a); return r; }, Object.create(null)); console.log(this.itemsGroup); { Sandwiches: [ { nombre: 'Sandwich de Pollo', precio: 12 }, { nombre: 'Sandwich de Pollo', precio: 15 } ], Helados: [ { nombre: 'Helado de 1 bola', precio: 5 }, { nombre: 'Helado de 2 bolas', precio: 8 }, { nombre: 'Helado de 3 bolas', precio: 10 } ] }Puedes hacerlo usando_.groupBy()
const items = [ { categoria: 'Sandwiches', nombre: 'Sandwich de Pollo', precio: 12 }, { categoria: 'Sandwiches', nombre: 'Sandwich de Lomo', precio: 12 }, { categoria: 'Helados', nombre: 'Helado de 1 bola', precio: 5 }, { categoria: 'Helados', nombre: 'Helado de 2 bolas', precio: 8 }, { categoria: 'Helados', nombre: 'Helado de 3 bolas', precio: 10 }, ]; let newArr = []; let grp = _.groupBy(items, "categoria"); for (const obj in grp) { newArr.push({ categoria: obj, items: grp[obj] }); } console.log(newArr, 'newArr'); Si no quieres underscore.js , ¡puedes hacerlo usando reduce() !
const items = [ { categoria: 'Sandwiches', nombre: 'Sandwich de Pollo', precio: 12 }, { categoria: 'Sandwiches', nombre: 'Sandwich de Lomo', precio: 12 }, { categoria: 'Helados', nombre: 'Helado de 1 bola', precio: 5 }, { categoria: 'Helados', nombre: 'Helado de 2 bolas', precio: 8 }, { categoria: 'Helados', nombre: 'Helado de 3 bolas', precio: 10 }, ]; let newArr = []; let grp = items.reduce((group, product) => { const { categoria } = product; group[categoria] = group[categoria] ?? []; group[categoria].push(product); return group; }, {}); for (const obj in grp) { newArr.push({ categoria: obj, items: grp[obj] }); } console.log(newArr, 'newArr');Mi solución:
const items = [ { categoria: "Sandwiches", nombre: "Sandwich de Pollo", precio: 12 }, { categoria: "Sandwiches", nombre: "Sandwich de Lomo", precio: 12 }, { categoria: "Helados", nombre: "Helado de 1 bola", precio: 5 }, { categoria: "Helados", nombre: "Helado de 2 bolas", precio: 8 }, { categoria: "Helados", nombre: "Helado de 3 bolas", precio: 10 } ]; const groupedArr = items.reduce((prev, { categoria, ...items }) => { const id = prev.findIndex((item) => item.categoria === categoria); id >= 0 ? prev[id].items.push(items) : prev.push({categoria, items: [items]}) return prev }, []); console.log(groupedArr);Creo que es más aclarable y corto que la solución de @MayurVaghasiya.
Además, no necesita dependencias.