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

Ruby on Rails中两个数组的时间段同步拆分实现方案咨询

Ruby on Rails 时间段拆分同步解决方案

你可以采用「收集所有时间边界→拆分最小独立区间→匹配属性」的思路实现,逻辑清晰且能覆盖所有重叠、单边存在的场景,实现代码如下:

def sync_time_periods(time_periods_a, time_periods_b)
  # 辅助方法:将原始哈希转成带Date类型起止的结构,方便比较
  parse_period = ->(period) {
    {
      start: Date.strptime(period[:start_date], '%d/%m/%Y'),
      end: Date.strptime(period[:end_date], '%d/%m/%Y'),
      value: period[:additional_attribute]
    }
  }
  a_periods = time_periods_a.map(&parse_period)
  b_periods = time_periods_b.map(&parse_period)

  # 收集所有边界点:所有时间段的开始时间、结束时间+1天
  boundary_dates = []
  a_periods.each do |p|
    boundary_dates << p[:start]
    boundary_dates << p[:end] + 1.day
  end
  b_periods.each do |p|
    boundary_dates << p[:start]
    boundary_dates << p[:end] + 1.day
  end
  # 去重排序
  boundary_dates = boundary_dates.uniq.sort

  result = []
  # 遍历相邻边界点,生成最小独立区间
  boundary_dates.each_cons(2) do |start_date, next_start|
    end_date = next_start - 1.day
    next if start_date > end_date

    # 匹配a数组中包含当前区间的属性值
    a_val = a_periods.find { |p| p[:start] <= start_date && p[:end] >= end_date }&.dig(:value) || 0
    # 匹配b数组中包含当前区间的属性值
    b_val = b_periods.find { |p| p[:start] <= start_date && p[:end] >= end_date }&.dig(:value) || 0

    # 转回原格式的日期字符串
    result << {
      start_date: start_date.strftime('%d/%m/%Y'),
      end_date: end_date.strftime('%d/%m/%Y'),
      additional_attribute_a: a_val,
      additional_attribute_b: b_val
    }
  end
  result
end

代码说明

  1. 先把输入的两个数组的时间段都转成带Date类型的结构,避免字符串比较的错误,注意这里用Date.strptime适配你输入的dd/mm/yyyy格式,如果你的实际日期格式不同可以调整第二个参数。
  2. 收集所有边界点:所有时间段的开始日期、结束日期+1天,去重排序后,相邻两个点之间就是没有任何重叠的最小独立区间。
  3. 遍历每个最小区间,分别去两个原始数组里找是否有包含当前区间的时间段,取对应的属性值,找不到就设为0。
  4. 最后把日期转回你需要的字符串格式,输出结果。

测试验证

用你给出的第一个示例调用:

time_periods_a = [
  { start_date: '01/10/2021', end_date: '31/10/2021', additional_attribute: 5 },
  { start_date: '01/11/2021', end_date: '30/11/2021', additional_attribute: 10 }
]
time_periods_b = [
  { start_date: '01/10/2021', end_date: '31/12/2021', additional_attribute: 20 }
]
puts sync_time_periods(time_periods_a, time_periods_b)

输出结果和你预期的完全一致。
第二个简化的月份示例同理,边界点收集完成后拆分的区间完全匹配你给出的预期输出。

原有代码问题

你之前的代码是按两个数组的索引一一对应处理,没有考虑跨索引的重叠、两个数组长度不一致的场景,所以会出现匹配错误的情况,上述方案完全避开了这个问题。

内容的提问来源于stack exchange,提问作者MrBobologo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:18:01