如何将星期数字数组转换为可跨周的日期名称范围?
我来帮你解决这个问题!你的核心痛点是处理跨周连续的日期块(比如周五、周六、周日、周一要合并成"Friday-Monday"),同时简化代码逻辑。咱们一步一步来:
首先,先明确原代码的问题:
- 没考虑「6(周六)之后接0(周日)属于连续」的情况
- 也没处理首尾区间跨周合并的场景
- 字符串拼接的逻辑过于繁琐,可读性差
解决方案思路
- 预处理输入:先对输入数组去重、排序,避免乱序或重复值干扰逻辑
- 生成连续区间:遍历排序后的数组,把连续的日期(包括6→0的跨周连续)归为同一个区间
- 跨周区间合并:如果首尾两个区间是跨周连续的(比如最后一个区间是[5,6],第一个是[0,1]),就把它们合并成一个跨周区间
- 转换为友好字符串:把每个区间转换成「单个日期」或「起始-结束日期」的格式
完整实现代码
const dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; function formatDays(days) { // 1. 去重并排序,确保日期按顺序排列 const sortedDays = [...new Set(days)].sort((a, b) => a - b); if (sortedDays.length === 0) return []; // 2. 生成连续日期区间 const intervals = []; let [currentStart, currentEnd] = [sortedDays[0], sortedDays[0]]; for (let i = 1; i < sortedDays.length; i++) { const currentDay = sortedDays[i]; const prevDay = sortedDays[i - 1]; // 判断是否连续:要么是前一天+1,要么是周六(6)接周日(0) if (currentDay === prevDay + 1 || (prevDay === 6 && currentDay === 0)) { currentEnd = currentDay; } else { // 不连续则保存当前区间,开始新的区间 intervals.push([currentStart, currentEnd]); [currentStart, currentEnd] = [currentDay, currentDay]; } } // 保存最后一个区间 intervals.push([currentStart, currentEnd]); // 3. 处理跨周合并:如果首尾区间是跨周连续的 if (intervals.length > 1) { const firstInterval = intervals[0]; const lastInterval = intervals.at(-1); // 检查最后一个区间的结束日+1 是否等于第一个区间的起始日(模7处理跨周) if ((lastInterval[1] + 1) % 7 === firstInterval[0]) { // 合并首尾区间 const mergedInterval = [lastInterval[0], firstInterval[1]]; intervals.pop(); intervals.shift(); intervals.unshift(mergedInterval); } } // 4. 转换为目标字符串格式 return intervals.map(([start, end]) => { if (start === end) return dayNames[start]; return `${dayNames[start]}-${dayNames[end]}`; }); } // 测试你的例子 console.log(formatDays([0,1,2,4,5])); // ["Sunday-Tuesday", "Thursday-Friday"] console.log(formatDays([0,1,3,5,6])); // ["Friday-Monday", "Wednesday"]
代码解释
- 预处理步骤:用
Set去重,再排序,保证后续逻辑只处理有序且唯一的日期值 - 区间生成:通过遍历判断当前日期是否和前一个连续,连续则扩展当前区间,否则保存当前区间并开启新的
- 跨周合并:通过
(lastInterval[1] + 1) % 7 === firstInterval[0]判断首尾是否跨周连续,是的话合并成一个区间 - 字符串转换:单个日期直接返回名称,区间则返回「起始-结束」的格式,跨周的情况(比如start=5,end=1)会自动生成"Friday-Monday",完全符合你的需求
对比原代码的优势
- 逻辑更清晰:用区间的方式处理连续日期,避免了繁琐的字符串拼接和切割
- 完美支持跨周场景:专门处理了6→0的连续情况,以及首尾区间的跨周合并
- 代码更简洁:去掉了冗余的字符串操作,用数组和区间的思路简化逻辑
内容的提问来源于stack exchange,提问作者tempomax




