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"]]
代码逻辑拆解
- 收集基准日期:先筛选出子数组里所有带
:的长日期,提取它们的纯日期部分(比如从"2019-02-01: 186904"得到"2019-02-01"),存入counted_date_bases数组。 - 精准过滤元素:
- 带
:的长日期直接保留; - 纯短日期仅当不在
counted_date_bases中时保留(说明没有对应的长日期版本),否则过滤删除。
- 带
这种方式避开了遍历中修改数组的问题,逻辑清晰且能精准实现你的需求。
内容的提问来源于stack exchange,提问作者Sandra Cieseck
相关产品推荐
相关产品推荐

