ES6 JavaScript嵌套数组映射:分组后元素访问与总价计算
问题与解决方案
原问题描述
我有一个数组,想按日期对其中的对象分组,用了以下函数:
const groupedDates= Object.entries( items.reduce((acc, { product, price, type, date }) => { if (!acc[date]) { acc[date] = []; } acc[date].push({ product, price, type date }); // 语法错误:type与date间缺少逗号 return acc; }, {}) ).map(([date, items]) => ({ date, items }));
原始数组:
const items = [ { id: 1, product: "milk", price: 10, type: "drink" // 语法错误:缺少逗号 date: "01/01/2022", }, { id: 2, product: "coca", price: 11, type: "drink" // 语法错误:缺少逗号 date: "01/01/2022", }, { id: 3, product: "pepsi", price: 20, type: "drink" // 语法错误:缺少逗号 date: "01/01/2024", }, { id: 4, product: "carrots", price: 30, type: "food", date: "01/01/2023", }, ];
分组后遇到两个问题:
- 无法安全访问组内的
items[1],直接访问会因为部分组只有一个元素而报错; - 需要计算每个日期对应的总价,制作包含「日期 + 总价 + 每个商品及单价」的卡片。
解决方案
1. 修复基础语法错误
先修正代码里的语法问题(这些错误会导致JS解析失败,也是后续问题的潜在诱因):
- 数组对象中
type属性后缺少逗号; push的对象里type和date之间缺少逗号。
修正后的基础分组函数:
const groupedDates = Object.entries( items.reduce((acc, { product, price, type, date }) => { if (!acc[date]) { acc[date] = []; } acc[date].push({ product, price, type, date }); // 修复逗号问题 return acc; }, {}) ).map(([date, items]) => ({ date, items }));
2. 安全访问组内所有商品
不要通过硬索引(比如items[0]、items[1])访问商品,而是遍历每个组的items数组,这样不管组内有多少个商品都能兼容:
// 示例:遍历渲染所有分组的商品 groupedDates.map(group => ( <div key={group.date} className="date-card"> <h3>{group.date}</h3> {/* 遍历当前日期下的所有商品 */} {group.items.map(item => ( <p key={item.product}>{item.product} - ${item.price}</p> ))} </div> ))
3. 计算每个日期的总价
可以在分组阶段同步计算总价(更高效),也可以在分组后单独计算,两种方式如下:
方式一:分组时同步计算总价
const groupedDates = Object.entries( items.reduce((acc, { product, price, type, date }) => { if (!acc[date]) { // 初始化分组时,同时创建items数组和totalPrice字段 acc[date] = { items: [], totalPrice: 0 }; } acc[date].items.push({ product, price, type, date }); acc[date].totalPrice += price; // 累加当前商品价格到总价 return acc; }, {}) ).map(([date, { items, totalPrice }]) => ({ date, items, totalPrice }));
方式二:分组后单独计算总价
如果不想修改原分组逻辑,可在后续map阶段计算:
const groupedDates = Object.entries( items.reduce((acc, { product, price, type, date }) => { if (!acc[date]) { acc[date] = []; } acc[date].push({ product, price, type, date }); return acc; }, {}) ).map(([date, items]) => ({ date, items, // 用reduce累加当前组所有商品的价格 totalPrice: items.reduce((sum, item) => sum + item.price, 0) }));
最终卡片渲染示例
拿到包含总价的分组数据后,可直接渲染目标卡片:
// React示例渲染逻辑 groupedDates.map(group => ( <div key={group.date} className="transaction-card"> <h2>日期:{group.date}</h2> <p className="total">总价:${group.totalPrice}</p> <div className="items-list"> {group.items.map(item => ( <div key={item.product} className="item"> <span>{item.product}</span> <span>${item.price}</span> </div> ))} </div> </div> ))
内容的提问来源于stack exchange,提问作者DavidNy
相关产品推荐
相关产品推荐

