如何使用JavaScript的reduce方法获取指定的分组预期结果?
如何将groupBy结果转换为指定的数组结构
当前你的groupBy函数返回一个以category为键、对应商品数组为值的对象,但需要将其转换为包含category和item属性的对象数组,以下是两种可行的解决方案:
方案一:先分组再转换(简洁高效)
保留原有的分组逻辑生成对象,再通过Object.entries()将对象转换为目标数组结构:
const PRODUCTS = [ { category: "Fruits", price: "$1", stocked: true, name: "Apple" }, { category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit" }, { category: "Fruits", price: "$2", stocked: false, name: "Passionfruit" }, { category: "Vegetables", price: "$2", stocked: true, name: "Spinach" }, { category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin" }, { category: "Vegetables", price: "$1", stocked: true, name: "Peas" }, ]; function groupBy(objectArray, property) { // 按原逻辑生成分组对象 const groupedObject = objectArray.reduce((prev, curr) => { const key = curr[property]; return { ...prev, [key]: [...(prev[key] ?? []), curr] }; }, {}); // 将分组对象转换为预期的数组结构 return Object.entries(groupedObject).map(([category, item]) => ({ category, item })); } console.log(groupBy(PRODUCTS, "category"));
原理说明:
Object.entries(groupedObject)将分组对象转换为[键, 值]形式的数组,例如[["Fruits", [...商品数组]], ["Vegetables", [...商品数组]]]。- 通过
map遍历每个键值对,将其重构为包含category(键)和item(值)的对象,最终得到目标数组。
方案二:直接在reduce中构建目标数组
如果希望一步到位,也可以直接在reduce过程中维护目标数组结构:
function groupBy(objectArray, property) { return objectArray.reduce((result, curr) => { const key = curr[property]; // 查找结果数组中是否已存在当前category的分组 const existingGroup = result.find(group => group.category === key); if (existingGroup) { // 若存在,将当前商品添加到对应分组的item数组中 existingGroup.item.push(curr); } else { // 若不存在,新增一个分组项 result.push({ category: key, item: [curr] }); } return result; }, []); // 初始值设为空数组 }
纯函数版本(可选):
如果需要避免修改原数据的纯函数实现,可以改用扩展运算符创建新对象:
function groupBy(objectArray, property) { return objectArray.reduce((result, curr) => { const key = curr[property]; const groupIndex = result.findIndex(group => group.category === key); if (groupIndex !== -1) { // 创建新的分组对象和数组,不修改原数据 return [ ...result.slice(0, groupIndex), { ...result[groupIndex], item: [...result[groupIndex].item, curr] }, ...result.slice(groupIndex + 1) ]; } else { return [...result, { category: key, item: [curr] }]; } }, []); }
这种实现不会修改原数据,但在数据量较大时性能略低于直接修改的方式,可根据场景选择。
内容的提问来源于stack exchange,提问作者DanNg
相关产品推荐
相关产品推荐

