You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

年份区间缺口识别与合并:政客政党成员数据处理技术问询

年份区间缺口识别与合并功能:代码验证与优化建议

需求背景

我正在实现一个年份区间缺口识别与合并功能,用于处理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;
    }

现有代码问题验证

  1. 类型定义错误:原yearRange接口的end字段仅定义为number,但需求中存在end: null的场景,会导致类型不兼容。
  2. 逻辑漏洞:
    • 多独立区间场景下,会错误将多个不相关的结束值绑定到同一个起始年份,无法正确保留区间缺口。
    • 未处理区间乱序情况:如果输入区间未按时间排序,逻辑会完全失效。
  3. 类型不安全:函数参数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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:20:55