如何在Ruby数组中移除连续重复元素而非全部重复元素?
移除Ruby数组中的连续重复元素
嘿,这个需求其实Ruby已经给我们准备了非常简洁的内置方法啦!先明确下你的问题:
你有这样一个数组:
arr = ['a','a','b','b','b','a','c']
想要移除连续重复的元素(注意不是arr.uniq那种移除所有重复项),预期输出是:
['a','b','a','c']
你自己已经写了一个遍历实现的方法,但想找更简洁的Ruby写法对吧?先贴一下你的尝试代码:
def remove_repeats arr new_arr = [] last_element = nil arr.each do |x| if last_element != x new_arr << x end last_element = x end new_arr end arr = ['a','a','b','b','b','a','c','c'] puts remove_repeats(arr).join(',') # => a,b,a,c
最简洁的几种实现方式
1. 用chunk_while(Ruby 2.3+推荐)
这是最直观也最Ruby风格的写法,专门处理连续元素分组的场景:
arr.chunk_while { |a, b| a == b }.map(&:first) # 输出结果:["a", "b", "a", "c"]
原理:chunk_while会把数组里连续相同的元素打包成子数组,原数组会被分成[["a", "a"], ["b", "b", "b"], ["a"], ["c"]],然后我们只需要取每个子数组的第一个元素就搞定了。
2. 用slice_when(逻辑相反的另一种选择)
和chunk_while是一对,当块里的条件满足时就分割数组,写法如下:
arr.slice_when { |a, b| a != b }.map(&:first) # 同样得到预期结果
3. 用inject(兼容更老Ruby版本)
如果需要兼容Ruby 2.3之前的版本,可以用inject把你的遍历逻辑压缩成一行:
arr.inject([]) { |result, elem| result.last == elem ? result : result << elem }
这个逻辑和你自己写的方法完全一致:用result保存结果数组,每次判断当前元素elem是否和result的最后一个元素相同,不同就添加进去,相同就跳过。
内容的提问来源于stack exchange,提问作者Axiombadger
相关产品推荐
相关产品推荐

