JavaScript中如何按weekDay字段分组对象数组并统计重复次数
问题描述
我想要对对象数组进行格式化,将包含相同weekDay值的数据合并到同一个对象中,比如有5个对象的weekDay都为1,那么最终得到的格式如下:
{...{}, weekDay:1, repeated:5}
目前数据是动态的,我可以写出硬编码的实现逻辑,比如筛选weekDay === 1的项再获取返回数组的长度,但我现在需要一个通用函数,接收该数据数组作为入参,返回去重后的完整数组,相同weekDay不会重复出现,同时携带对应的重复次数,格式同上。
现有测试数据
[ { "weekDay": 1, "role": "admin" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 1, "role": "creator" }, { "weekDay": 1, "role": "creator" }, { "weekDay": 1, "role": "creator" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 2, "role": "screener" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 3, "role": "screener" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 2, "role": "screener" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 3, "role": "creator" }, { "weekDay": 3, "role": "creator" }, { "weekDay": 3, "role": "screener" }, { "weekDay": 4, "role": "creator" }, { "weekDay": 3, "role": "screener" }, { "weekDay": 3, "role": "creator" }, { "weekDay": 3, "role": "screener" }, { "weekDay": 4, "role": "screener" }, { "weekDay": 4, "role": "screener" }, { "weekDay": 4, "role": "screener" }, { "weekDay": 5, "role": "screener" }, { "weekDay": 4, "role": "screener" }, { "weekDay": 4, "role": "creator" }, { "weekDay": 4, "role": "screener" }, { "weekDay": 5, "role": "screener" }, { "weekDay": 5, "role": "screener" }, { "weekDay": 5, "role": "creator" }, { "weekDay": 6, "role": "creator" }, { "weekDay": 5, "role": "screener" }, { "weekDay": 1, "role": "screener" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 1, "role": "screener" }, { "weekDay": 1, "role": "screener" }, { "weekDay": 1, "role": "creator" }, { "weekDay": 2, "role": "screener" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 3, "role": "creator" }, { "weekDay": 2, "role": "creator" }, { "weekDay": 2, "role": "screener" }, { "weekDay": 2, "role": "screener" }, { "weekDay": 3, "role": "screener" }, { "weekDay": 34, "role": "creator" } ]
解决方案
实现逻辑
用哈希映射统计每个weekDay的出现次数,单次遍历即可完成统计,时间复杂度为O(n),性能远高于硬编码的多次筛选方案。如果需要保留原对象的其他属性,可以在初始化映射项时直接展开原对象。
通用函数代码
function mergeSameWeekDay(arr) { const weekDayMap = {} arr.forEach(item => { const currentWeekDay = item.weekDay // 首次出现的weekDay初始化统计项 if (!weekDayMap[currentWeekDay]) { // 要保留原对象其他属性的话,改成 weekDayMap[currentWeekDay] = {...item, repeated: 0} weekDayMap[currentWeekDay] = { weekDay: currentWeekDay, repeated: 0 } } weekDayMap[currentWeekDay].repeated += 1 }) // 将映射对象转为数组返回 return Object.values(weekDayMap) }
返回结果示例
将你提供的测试数据传入函数后,返回结果如下:
[ { weekDay: 1, repeated: 8 }, { weekDay: 2, repeated: 14 }, { weekDay: 3, repeated: 10 }, { weekDay: 4, repeated: 7 }, { weekDay: 5, repeated: 5 }, { weekDay: 6, repeated: 1 }, { weekDay: 34, repeated: 1 } ]
内容的提问来源于stack exchange,提问作者Muhammad Hussain
相关产品推荐
相关产品推荐

