Traté de encontrar una solución a mi problema pero no pude encontrar una, así que tengo una matriz de objetos (productos), cada producto tiene una propiedad de categoría y quiero agrupar los productos por categorías. Me las arreglé para hacer eso usando reduce() pero ahora necesitaría representar primero el nombre de la categoría y luego los productos en esa categoría.
Ejemplo:
const products = [ {id: 1, category: 'Burgers', name: 'Burger'}, {id: 2, category: 'Burgers', name: 'Cheeseburger'}, {id: 3, category: 'Meals', name: 'Burger meal'}, {id: 4, category: 'Meals', name: 'Cheeseburger meal'} ]Necesito agrupar estos productos por categoría y lo hice con reduce()
const menu = products.reduce((menu, product) => { if (menu[product.category] == null) menu[product.category] = [] menu[product.category].push(product) return menu }, [])Así que ahora mi resultado es
[Burgers: Array(2), Meals: Array(2)]Pero me gustaría representarlos con map(), entonces, ¿cómo puedo hacer eso? O como puedo cambiar el resultado? me gustaría que el resultado fuera como
Categories: [ { 0: name: 'Burgers', products: Array(2) }, { 1: name: 'Meals', products: Array(2) } ]De esa manera podría representar esa matriz con un mapa como
<div> {menu.map((c, index) => <Category key={index} name={c.name} products={c.products} /> )} </div> const products = [ {id: 1, category: 'Burgers', name: 'Burger'}, {id: 2, category: 'Burgers', name: 'Cheeseburger'}, {id: 3, category: 'Meals', name: 'Burger meal'}, {id: 4, category: 'Meals', name: 'Cheeseburger meal'} ] const menu = products.reduce((acc, product)=> { const categoryIndex = acc.findIndex(item => item.name == product.category); if(categoryIndex > -1){ acc[categoryIndex].products.push(product); }else { acc.push({ name: product.category, products: [product] }) }; return acc; }, []); console.log(menu)Al principio, solo estaba respondiendo la pregunta de javascript puro sobre cómo agrupar
products.reduce((prev, curr) => { if(!prev.categories.hasOwnProperty(curr.category)) prev.categories[curr.category] = prev.count++ const index = prev.categories[curr.category] if(!Array.isArray(prev.menu[index])) prev.menu[index] = [] prev.menu[index].push(curr) return prev }, {count: 0, menu: [], categories:{}}).menuA partir de ahí, supongo que tu mapa se vería así:
<div> {menu.forEach((c, i) => <Category key={i} name={c[0].category} products={c} /> )} </div>