基于roomId合并嵌套数组并统计日期频次的实现咨询
按roomId合并日期数组并统计频次的解决方案
问题描述
现有一组包含roomId与nights数组的对象,需根据roomId合并同一ID对应的nights数组,同时统计每个日期的出现频次。尝试过map、reduce函数但未得到预期结果,寻求解决方案。
输入示例
const data = [ {roomId: 1, nights: [ "2022-05-06", "2022-05-07" ] }, {roomId: 2, nights: [ "2022-05-06", "2022-05-07", "2022-05-08" ] }, {roomId: 1, nights: [ "2022-05-10", "2022-05-11", "2022-05-07", ] }, {roomId: 2, nights: [ "2022-05-12", "2022-05-13", "2022-05-14" ] } ];
期望输出
const newObject = [ {roomId: 1, nights: [ {date:"2022-05-06", count:1}, {date:"2022-05-07", count:2}, {date:"2022-05-10", count:1}, {date:"2022-05-11", count:1} ] }, {roomId: 2, nights: [ {date:"2022-05-06",count:1}, {date:"2022-05-07",count:1}, {date:"2022-05-08",count:1}, {date:"2022-05-12",count:1}, {date:"2022-05-13",count:1}, {date:"2022-05-14",count:1} ] }, ];
解决方案
可以通过两次reduce配合map实现需求,分两步完成:
- 按
roomId分组,合并同一房间的所有日期数组 - 对每个房间的日期数组统计频次,转换为目标格式
具体代码如下:
const data = [ {roomId: 1, nights: ["2022-05-06", "2022-05-07"]}, {roomId: 2, nights: ["2022-05-06", "2022-05-07", "2022-05-08"]}, {roomId: 1, nights: ["2022-05-10", "2022-05-11", "2022-05-07"]}, {roomId: 2, nights: ["2022-05-12", "2022-05-13", "2022-05-14"]} ]; // 第一步:按roomId分组,合并所有日期 const groupedRooms = data.reduce((acc, current) => { const existingRoom = acc.find(room => room.roomId === current.roomId); if (existingRoom) { existingRoom.nights.push(...current.nights); } else { acc.push({...current}); } return acc; }, []); // 第二步:统计每个日期的出现次数并转换格式 const result = groupedRooms.map(room => { const dateCountMap = room.nights.reduce((map, date) => { map[date] = (map[date] || 0) + 1; return map; }, {}); return { roomId: room.roomId, nights: Object.entries(dateCountMap).map(([date, count]) => ({date, count})) }; }); console.log(result);
代码说明
- 第一阶段的
reduce遍历原始数据,将相同roomId的对象合并,把所有nights数组拼接成一个包含该房间所有日期的数组。 - 第二阶段先通过
reduce生成日期到频次的映射对象,再用Object.entries将映射转换为{date, count}格式的数组,最终得到符合要求的结构。
内容的提问来源于stack exchange,提问作者Code4fun
相关产品推荐
相关产品推荐

