如何对数字数组中的连续范围合并以缩短URL查询字符串?
问题描述
客户端表格支持行选择,每行对应唯一数字ID。编辑选中行时需通过URL查询字符串传递这些ID,但URL长度有限制,因此需要将选中的ID列表压缩为最短格式:把连续数字范围用起始值:结束值表示,单个数字直接保留,最终用逗号分隔所有项。例如输入[5, 7, 8, 9, 77, 288],需输出"5:9,77,288"。
解决方案
核心逻辑
- 排序去重:先对ID列表升序排序,可选去重(避免重复ID干扰范围识别)
- 范围追踪:遍历排序后的列表,维护当前连续范围的起始和结束值
- 范围判断:若下一个ID是当前结束值+1,则扩展当前范围;否则将当前范围格式化后存入结果,重置范围为当前ID
- 收尾处理:遍历结束后,将最后一个范围加入结果列表
- 拼接结果:用逗号连接所有范围项,得到最短格式字符串
代码示例(JavaScript)
function compressIds(idList) { if (!idList || idList.length === 0) return ''; // 排序并去重(去重可根据业务场景省略) const sortedUniqueIds = [...new Set(idList)].sort((a, b) => a - b); const result = []; let currentStart = sortedUniqueIds[0]; let currentEnd = sortedUniqueIds[0]; for (let i = 1; i < sortedUniqueIds.length; i++) { const id = sortedUniqueIds[i]; if (id === currentEnd + 1) { currentEnd = id; } else { // 格式化当前范围并加入结果 result.push(currentStart === currentEnd ? `${currentStart}` : `${currentStart}:${currentEnd}`); currentStart = id; currentEnd = id; } } // 加入最后一个范围 result.push(currentStart === currentEnd ? `${currentStart}` : `${currentStart}:${currentEnd}`); return result.join(','); } // 测试用例 console.log(compressIds([5, 7, 8, 9, 77, 288])); // 输出 "5:9,77,288" console.log(compressIds([1,2,3,5,6,8])); // 输出 "1:3,5:6,8" console.log(compressIds([10])); // 输出 "10" console.log(compressIds([])); // 输出 ""
注意事项
- 必须排序:未排序的ID列表无法正确识别连续范围,排序是实现的基础
- 去重可选:如果业务逻辑中不会出现重复选中同一行的情况,可以去掉去重步骤以提升性能
- 空值处理:空列表返回空字符串,避免生成无效的URL查询参数
内容的提问来源于stack exchange,提问作者MisterHow
相关产品推荐
相关产品推荐

