I’m trying to understand the .reduce()
function and the best way to go about the following.
I’ve got the following code:
const products = [ { name: 'apples', category: 'fruits' }, { name: 'oranges', category: 'fruits' }, { name: 'potatoes', category: 'vegetables' } ]; const groupByCategory = products.reduce((group, product) => { const { category } = product; group[category] = group[category] ?? []; group[category].push(product); return group; }, {});
I want to add a product with no ‘category’ property in it, and I want it pushed into a specific key rather than getting grouped in “undefined”, so I edited it to:
const products = [ { name: "apples", category: "fruits" }, { name: "oranges", category: "fruits" }, { name: "potatoes", category: "vegetables" }, { name: "guava"} ]; const groupByCategory = products.reduce((group, product) => { const { category } = product ; // check if 'category' exists, if it doesn't store it as an empty array to push to group[category] = group[category] ?? []; // if category is undefined, push it into 'nocategory'. Otherwise push into relevant. if(!category){ group['nocategory'].push(product); } else { group[category].push(product); }; return group; }, {'nocategory':[]}); console.log(JSON.stringify(groupByCategory, null, 2));
For the most part it works (there’s still an ‘undefined’ group, but at least the object gets pushed into the right group).
I’m sure there’s a better solution/proper way to do this. Any pointers would be appreciated.
Advertisement
Answer
Instead of a whole new conditional block you could just set a default in the destructuring and then group as usual.
const { category = 'nocategory' } = product;
const products = [ { name: "apples", category: "fruits" }, { name: "oranges", category: "fruits" }, { name: "potatoes", category: "vegetables" }, { name: "guava"} ]; const groupByCategory = products.reduce((group, product) => { const { category = 'nocategory' } = product; group[category] ??= []; group[category].push(product); return group; }, {}); console.log(JSON.stringify(groupByCategory, null, 2));
Note: you can also make use of logical nullish assignment (??=)