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

Ruby嵌套数组去重:保留带计数日期字符串的代码修复

解决嵌套数组中日期字符串的去重问题

你遇到的核心需求是:在每个子数组里保留带计数的长日期格式(如"2019-02-01: 186904"),同时删除对应的纯短日期(如"2019-02-01")。原代码没达到预期,主要是因为遍历数组的同时修改数组会导致元素跳过,且逻辑判断的精准度不够。

原代码的问题分析

你的日期提取逻辑(从长日期中剥离纯日期部分)是对的,但直接在each遍历中调用topic.delete(el)会踩坑:数组在遍历过程中被修改,元素索引会动态变化,导致部分元素被跳过检查。比如删除一个元素后,后面的元素会前移,each会直接跳过下一个元素,最终有些该删除的短日期没被处理。

修正后的解决方案

我们换个思路:先收集每个子数组里所有带计数日期的纯日期部分,再通过过滤逻辑保留符合要求的元素——要么是带计数的长日期,要么是没有对应长日期的纯短日期。

具体代码实现

def clean_date_arrays(original_arr)
  original_arr.map do |topic_group|
    # 第一步:收集所有带计数日期的纯日期部分
    counted_date_bases = topic_group.select { |item| item.include?(': ') }.map do |counted_item|
      counted_item.match(/^\d{4}-\d{2}-\d{2}/)[0]
    end

    # 第二步:过滤当前子数组,保留目标元素
    topic_group.select do |item|
      if item.include?(': ')
        true # 直接保留带计数的长日期
      else
        # 纯短日期仅在没有对应长日期时保留
        !counted_date_bases.include?(item)
      end
    end
  end
end

# 测试验证
doc_count = [ ["foo", "2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"], ["bar", "2019-01-01: 8876", "2019-04-01: 8694", "2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"] ]
goal = clean_date_arrays(doc_count)
p goal
# 输出与预期一致:
# [["foo", "2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01", "2019-04-01"], ["bar", "2019-01-01: 8876", "2019-04-01: 8694", "2019-02-01", "2019-03-01"]]

代码逻辑拆解

  1. 收集基准日期:先筛选出子数组里所有带: 的长日期,提取它们的纯日期部分(比如从"2019-02-01: 186904"得到"2019-02-01"),存入counted_date_bases数组。
  2. 精准过滤元素:
    • 带: 的长日期直接保留;
    • 纯短日期仅当不在counted_date_bases中时保留(说明没有对应的长日期版本),否则过滤删除。

这种方式避开了遍历中修改数组的问题,逻辑清晰且能精准实现你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:48:16