删除Ruby数组中的冗余或重复元组

想象一下下面的Ruby数组:

[9, 9, 5, 5, 5, 2, 9, 9] 

删除多余元组的最简单方法是什么,产生如下输出:

 [9, 5, 2, 9] 

uniq不正确,因为它正在检查整个数组。 输入的顺序很重要,必须保留。 对此有直接的解决方法吗?

谢谢!

我会使用Enumerable#chunk

 2.0.0-p0 :001 > a = [9, 9, 5, 5, 5, 2, 9, 9] => [9, 9, 5, 5, 5, 2, 9, 9] 2.0.0-p0 :002 > a.chunk { |e| e }.map(&:first) => [9, 5, 2, 9] 

我会这样做的

 b = []; a.each { |n| b << n if b.last != n } 

b是结果

只需要一次arrays扫描

我最喜欢Arup的答案,但是如果你想要一个与没有chunk版本兼容的方法,你可以做

 a = [9, 9, 5, 5, 5, 2, 9, 9] a.inject([a[0]]) { |b,c| b.last == c ? b : b << c } # => [9, 5, 2, 9] 

这是我的版本:

 a.each_with_object([]) { |el, arr| arr << el if arr.last != el } #=> [9, 5, 2, 9] 

对于那些希望删除“冗余”值的问题,OP试图删除“重复连续”值,而不是“冗余”或“重复”值并使用错误的单词。 他们是不同的情况。

为了澄清,删除多余或重复的值将是:

 asdf = [9, 9, 5, 5, 5, 2, 9, 9] asdf.uniq # => [9, 5, 2] 

要么:

 asdf & asdf # => [9, 5, 2] 

要么:

 require 'set' asdf.to_set.to_a # => [9, 5, 2] 

而且,是的,我知道OP正在要求不同的结果。 这是为了显示所提问题的答案,而不是满足所需输出的答案。 为此,请参阅所选答案。

这是为了展示如何使用Enumerator#next和Enumerator#peek方法直接使用枚举器。

 def purge_conseq_dups(arr) return arr if arr.empty? enum = arr.to_enum a = [] loop do e = enum.next a << e unless e == enum.peek end a << arr.last end asdf = [9, 9, 5, 5, 5, 2, 9, 9] purge_conseq_dups(asdf) #=> [9, 5, 2, 9] 
  • e是枚举器enum的最后一个元素时, enum.peek引发一个StopInterationexception,它由Kernel#loop挽救,它通过断开循环来响应。 此时剩下的就是将arr的最后一个元素追加到a
  • 我们可以写a << e而不是a << arr.last ,只要我们在循环之前初始化e (例如, e = nil ),这样变量将在最后一行的范围内。