年份区间缺口识别与合并:政客政党成员数据处理技术问询
年份区间缺口识别与合并功能:代码验证与优化建议
需求背景
我正在实现一个年份区间缺口识别与合并功能,用于处理API返回的政客政党成员数据,解决政客更换/重新加入政党时的年份区间处理问题。核心需求如下:
- 合并首尾衔接的区间:例如
[{start: 2002, end: 2020}, {start: 2020, end: null}]合并为{start: 2002, end: null} - 保留存在缺口的独立区间:例如
[{start:2002, end:2004},{start:2006, end:2008}, {start:2008, end: null}]合并为[{start:2002, end:2004}, {start:2006, end: null}]
我编写了以下TypeScript代码实现该功能,希望得到技术验证和优化建议:
interface yearRange{ start: number end: number } function checkYearGaps(yearRanges: any[]) { let startYears: number[] = []; let endYears: (number | null)[] = []; let period: (number | null)[] = []; for (let y of yearRanges) { startYears.push(y.start); endYears.push(y.end); } let matchedEndYears: (number | null)[] = []; let unmatchedEndYears: (number | null)[] = []; for (let e of endYears) { const found = startYears.find((s) => s == e); if (found) { matchedEndYears.push(found); } else if (!found) { unmatchedEndYears.push(e); } } if (unmatchedEndYears.length > 0) { let start: number; for (let e of unmatchedEndYears) { let lesser: number[] = []; if (e == null) { if (startYears.length > 1) { start = Math.min(...startYears); } else { start = startYears[0]; } } else if (e != null) { lesser = startYears.filter((s) => s < e); start = Math.max(...lesser); } period.push({ start: start, end: e }); } } else if (unmatchedEndYears.length == 0) { let start: number = Math.min(...startYears); let end: number | null; if (endYears.includes(null)) { end = null; } else { end = Math.max(...endYears); } period.push({ start: start, end: end }); } console.log(period); return period; }
现有代码问题验证
- 类型定义错误:原
yearRange接口的end字段仅定义为number,但需求中存在end: null的场景,会导致类型不兼容。 - 逻辑漏洞:
- 多独立区间场景下,会错误将多个不相关的结束值绑定到同一个起始年份,无法正确保留区间缺口。
- 未处理区间乱序情况:如果输入区间未按时间排序,逻辑会完全失效。
- 类型不安全:函数参数
yearRanges: any[]无类型约束,容易传入不符合格式的数据引发错误。
优化方案
1. 修正类型定义
完善接口支持end为null,并给参数添加类型约束:
interface YearRange { start: number; end: number | null; } function mergeYearRanges(yearRanges: YearRange[]): YearRange[] { // 实现逻辑 }
2. 核心逻辑重构(正确合并算法)
正确的合并步骤应遵循:先排序,再遍历衔接合并,具体实现:
interface YearRange { start: number; end: number | null; } function mergeYearRanges(yearRanges: YearRange[]): YearRange[] { if (yearRanges.length === 0) return []; // 按起始年份升序排序,确保处理顺序正确 const sortedRanges = [...yearRanges].sort((a, b) => a.start - b.start); // 初始化结果数组,放入第一个区间 const merged: YearRange[] = [sortedRanges[0]]; for (let i = 1; i < sortedRanges.length; i++) { const current = sortedRanges[i]; const lastMerged = merged[merged.length - 1]; // 检查当前区间是否与最后一个合并区间首尾衔接 if (lastMerged.end !== null && lastMerged.end === current.start) { // 合并区间:更新最后一个区间的结束值 merged[merged.length - 1] = { start: lastMerged.start, end: current.end }; } else { // 存在缺口,直接添加为新区间 merged.push(current); } } return merged; }
3. 测试验证
用需求示例测试:
- 示例1:
mergeYearRanges([{start:2002, end:2020}, {start:2020, end:null}])→ 返回[{start:2002, end:null}],符合预期。 - 示例2:
mergeYearRanges([{start:2002, end:2004}, {start:2006, end:2008}, {start:2008, end:null}])→ 返回[{start:2002, end:2004}, {start:2006, end:null}],符合预期。
4. 额外优化点
- 输入校验:添加年份有效性检查(如
start为正整数,end不为null时需≥start)。 - 空输入处理:输入为空数组时直接返回空,避免报错。
- 性能优化:排序时间复杂度为O(n log n),遍历为O(n),满足绝大多数业务场景需求。
内容的提问来源于stack exchange,提问作者hoker7
相关产品推荐
相关产品推荐

