消除列表元素的连续重复

消除连续重复列表元素的最佳解决方案是什么?

list = compress(['a','a','a','a','b','c','c','a','a','d','e','e','e','e']). p list # => # ['a','b','c','a','d','e'] 

我有这个:

 def compress(list) list.map.with_index do |element, index| element unless element.equal? list[index+1] end.compact end 

Ruby 1.9.2

很好的机会使用Enumerable#chunk ,只要你的列表不包含nil

 list.chunk(&:itself).map(&:first) 

对于早于2.2.x的Ruby,您可以require "backports/2.2.0/kernel/itself"或使用{|x| x} {|x| x}而不是(&:itself)

对于早于1.9.2的Ruby,您可以require "backports/1.9.2/enumerable/chunk"来获得它的纯Ruby版本。

这样做(假设每个元素都是单个字符)

 list.join.squeeze.split('') 

Ruby 1.9+

 list.select.with_index{|e,i| e != list[i+1]} 

关于@sawa,谁告诉我with_index 🙂

正如@ Marc-AndréLafortune注意到,如果列表末尾有零,则不适合您。 我们可以用这个丑陋的结构修复它

 list.select.with_index{|e,i| i < (list.size-1) and e != list[i+1]} 
 # Requires Ruby 1.8.7+ due to Object#tap def compress(items) last = nil [].tap do |result| items.each{ |o| result << o unless last==o; last=o } end end list = compress(%w[ aaaabccaadeeee ]) p list #=> ["a", "b", "c", "a", "d", "e"] 
 arr = ['a','a','a','a','b','c','c','a','a','d','e','e','e','e'] enum = arr.each #=> # a = [] loop do n = enum.next a << n unless n == enum.peek end a #=> ["a", "b", "c", "a", "d"] 

枚举器 StopIteration在已经返回枚举器的最后一个元素时引发StopIterationexception。 内核#循环通过断开循环来处理该exception。

请参阅Array#each和Enumerator#next 。 可以使用内核#to_enum 1代替Array#each

1 to_enum是一个Object实例方法,它在Kernel模块中定义,但在Object类中有记录。 了解?