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

时间:2014-01-22 20:34:30

标签: ruby-on-rails ruby

想象一下以下的Ruby数组:

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

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

[9, 5, 2, 9]

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

谢谢!

6 个答案:

答案 0 :(得分:20)

我会使用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]

答案 1 :(得分:6)

我会这样做

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

b是结果

只需要一次阵列扫描

答案 2 :(得分:2)

我最喜欢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]

答案 3 :(得分:2)

这是我的版本:

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

答案 4 :(得分:1)

对于那些希望删除“冗余”值的问题的人,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正在要求不同的结果。这是为了显示被问到的问题的答案, NOT 什么会满足所需的输出。为此,请参阅选定的答案。

答案 5 :(得分:0)

这是为了展示如何使用方法Enumerator#nextEnumerator#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会引发由Kernel#loop救出的StopInteration异常,该异常以爆发形式作出回应循环。此时剩下的就是将arr的最后一个元素附加到a
  • 我们可以写a << e而不是a << arr.last,只要我们在循环之前初始化e(例如e = nil),这样变量就会在最后一行。