React.js中按指定分组条件归约数组的实现方法咨询
数组分组归约需求实现
现有数组
const array = [ { id: 1, count: 0.5, cost: 100, user: {id: 1, name: "John 1"}, type: {id: 1, name: "T1"}, period: {id: 1, name: "2021"} }, { id: 2, count: 2.5, cost: 200, user: {id: 1, name: "John 1"}, type: {id: 2, name: "T2"}, period: {id: 2, name: "2022"} }, { id: 3, count: 2.5, cost: 400, user: {id: 1, name: "John 1"}, type: {id: 2, name: "T2"}, period: {id: 2, name: "2022"} }, { id: 4, count: 1.5, cost: 100, user: {id: 2, name: "John 2"}, type: {id: 1, name: "T1"}, period: {id: 1, name: "2021"} }, { id: 5, count: 0.5, cost: 500, user: {id: 3, name: "John 3"}, type: {id: 1, name: "T1"}, period: {id: 1, name: "2021"} } ]
需求说明
按 user.id、period.id、type.id 三个维度分组归约,同分组下count值固定一致,分为两种归约规则:
- 第一种:分组后
cost字段为同分组所有项的cost求和结果 - 第二种:分组后
cost字段为同分组所有项的cost值组成的集合
实现方案
采用哈希映射实现分组,仅需遍历一次原数组,性能远高于反复用some、filter遍历的写法,同时避免重复项问题。
第一种归约(cost求和)
function groupAndSumCost(arr) { const groupMap = {}; let newId = 1; arr.forEach(item => { // 生成分组唯一标识 const groupKey = `${item.user.id}-${item.period.id}-${item.type.id}`; if (!groupMap[groupKey]) { // 首次匹配分组时初始化分组项 groupMap[groupKey] = { id: newId++, count: item.count, cost: 0, user: {...item.user}, type: {...item.type}, period: {...item.period} }; } // 累加同分组cost值 groupMap[groupKey].cost += item.cost; }); // 哈希对象转数组返回 return Object.values(groupMap); } const array1 = groupAndSumCost(array);
第二种归约(cost存集合)
function groupAndCollectCost(arr) { const groupMap = {}; let newId = 1; arr.forEach(item => { const groupKey = `${item.user.id}-${item.period.id}-${item.type.id}`; if (!groupMap[groupKey]) { groupMap[groupKey] = { id: newId++, count: item.count, cost: [], user: {...item.user}, type: {...item.type}, period: {...item.period} }; } // 收集cost值,若需要示例中[{200},{400}]的对象格式,可改为push({[item.cost]: item.cost}) groupMap[groupKey].cost.push(item.cost); }); // 单元素集合转成直接存数值,和示例输出对齐 Object.values(groupMap).forEach(group => { if (group.cost.length === 1) { group.cost = group.cost[0]; } }) return Object.values(groupMap); } const array2 = groupAndCollectCost(array);
内容的提问来源于stack exchange,提问作者bonnegnu
相关产品推荐
相关产品推荐

