Ruby 如何在数组中合并连续的重复元素?

Ruby 如何在数组中合并连续的重复元素?,ruby,Ruby,我需要在数组中合并连续的重复元素,这样 [1, 2, 2, 3, 1] 变成 [1, 2, 3, 1] #uniq不适用于此目的。为什么?因为#uniq将产生以下结果: [1, 2, 3] 做!uniq不适合您的工作 这将返回一个新数组,如uniq在O(n)时间内执行和工作。sepp2k的答案已经被接受,但这里有一些替代方案: # Because I love me some monkeypatching class Array def remove_consecutive_dupl

我需要在数组中合并连续的重复元素,这样

[1, 2, 2, 3, 1]
变成

[1, 2, 3, 1]
#uniq
不适用于此目的。为什么?因为
#uniq
将产生以下结果:

[1, 2, 3]

!uniq
不适合您的工作


这将返回一个新数组,如
uniq
O(n)
时间内执行和工作。

sepp2k的答案已经被接受,但这里有一些替代方案:

# Because I love me some monkeypatching
class Array
  def remove_consecutive_duplicates_2
    # Because no solution is complete without inject
    inject([]){ |r,o| r << o unless r.last==o; r }
  end

  def remove_consecutive_duplicates_3
    # O(2n)
    map.with_index{ |o,i| o if i==0 || self[i-1]!=o }.compact
  end

  def remove_consecutive_duplicates_4
    # Truly O(n)
    result = []
    last   = nil
    each do |o|
      result << o unless last==o
      last = o
    end
    result
  end
end

基准测试运行于从
orig=(0..1000)中删除重复项。映射{rand(5)}
10000次。

核心中有一个抽象,基本上完成了这项工作:


为什么uniq不工作?您使用的是uniq还是uniq!?另见重复问题。-1)他在回答中说它不起作用,2)它是uniq!不uniq
!uniq
在ruby中不是有效的方法名<代码>uniq与uniq执行相同的操作,但在适当的位置。所以这不是OP想要的(因为他只想删除连续的副本)。我没有注意到“连续的”副本要求。OP可能想解释一下。我刚刚补充了这个澄清。谢谢。我不知道每个缺点,很好!比公认的答案短得多、更干净、更高效。但是,如果数组中有nil值,这将无法正常工作,因为这将导致丢弃这些值。这一点很好。我不知道
chunk
有这些特殊值。如果输入可以有这些特殊值,那么它们都应该被包装。
# Because I love me some monkeypatching
class Array
  def remove_consecutive_duplicates_2
    # Because no solution is complete without inject
    inject([]){ |r,o| r << o unless r.last==o; r }
  end

  def remove_consecutive_duplicates_3
    # O(2n)
    map.with_index{ |o,i| o if i==0 || self[i-1]!=o }.compact
  end

  def remove_consecutive_duplicates_4
    # Truly O(n)
    result = []
    last   = nil
    each do |o|
      result << o unless last==o
      last = o
    end
    result
  end
end
Rehearsal --------------------------------------------
sepp2k     2.740000   0.010000   2.750000 (  2.734665)
Phrogz_2   1.410000   0.000000   1.410000 (  1.420978)
Phrogz_3   1.520000   0.020000   1.540000 (  1.533197)
Phrogz_4   1.000000   0.000000   1.000000 (  0.997460)
----------------------------------- total: 6.700000sec

               user     system      total        real
sepp2k     2.780000   0.000000   2.780000 (  2.782354)
Phrogz_2   1.450000   0.000000   1.450000 (  1.440868)
Phrogz_3   1.530000   0.020000   1.550000 (  1.539190)
Phrogz_4   1.020000   0.000000   1.020000 (  1.025331)
xs = [1, 2, 2, 3, 3, 3, 1]
xs.chunk { |x| x }.map(&:first)
#=> [1, 2, 3, 1]