如何按数值差值阈值将有序数组拆分为多个子数组
有序数组按相邻差值阈值拆分的优化实现
原实现存在的可优化点
- 阈值硬编码为2,无法灵活适配不同拆分规则,比如阈值为8的场景需要手动修改内部判断逻辑
- 依赖lodash的
_.last方法,引入了不必要的外部依赖 - 冗余的空数组判断分支、
continue流程跳转,逻辑分支稍显零散 - 循环结束后需要手动把临时拼接的子数组推入结果集,属于额外的边界收尾步骤,存在遗漏风险
优化后的实现方案
基于Array.reduce的归组逻辑,相比手写for循环的累加写法,代码逻辑和“逐元素判断归组”的目标更对齐,可读性更强,也去掉了外部依赖:
/** * 拆分有序升序数组为相邻元素差值不超过阈值的子数组 * @param {number[]} sortedAscArray 已升序排列的输入数组 * @param {number} maxAllowedDiff 同一子数组内相邻元素的最大允许差值 * @returns {number[][]} 拆分后的二维数组 */ function splitArray(sortedAscArray = [], maxAllowedDiff = 2) { return sortedAscArray.reduce((groupResult, currentVal) => { // 获取当前已生成的最后一个子数组 const lastGroup = groupResult.at(-1); // 超阈值时新建子数组,否则加入已有最后一个子数组 if (!lastGroup || currentVal - lastGroup.at(-1) > maxAllowedDiff) { groupResult.push([currentVal]); } else { lastGroup.push(currentVal); } return groupResult; }, []); }
效果验证
用你给出的两个测试场景验证:
- 阈值为2时的输出:
splitArray([1, 3, 5, 8, 10, 12, 21, 23], 2) // 结果:[[1, 3, 5], [8, 10, 12], [21, 23]]
- 阈值为8时的输出:
splitArray([1, 3, 5, 8, 10, 12, 21, 23], 8) // 结果:[[1, 3, 5, 8, 10, 12], [21, 23]]
兼容提示
Array.at(-1)是ES2022新增的取数组末尾元素的方法,在现代浏览器、Node.js 16+环境可直接使用;如果需要兼容老旧运行环境,将所有取末尾元素的xxx.at(-1)替换为xxx[xxx.length - 1]即可,逻辑完全不变。- 该逻辑默认输入数组为升序排列,如果输入数组为无序数组,需要将差值判断修改为
Math.abs(currentVal - lastGroup.at(-1))保证正负差值都能被正确识别。
内容的提问来源于stack exchange,提问作者Bertuz
相关产品推荐
相关产品推荐

