想象一下以下的Ruby数组:
[9, 9, 5, 5, 5, 2, 9, 9]
删除多余元组的最简单方法是什么,产生如下输出:
[9, 5, 2, 9]
uniq
不正确,因为它正在检查整个数组。输入的顺序很重要,必须保留。对此有直接的解决方法吗?
谢谢!
答案 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#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
会引发由Kernel#loop救出的StopInteration
异常,该异常以爆发形式作出回应循环。此时剩下的就是将arr
的最后一个元素附加到a
。a << e
而不是a << arr.last
,只要我们在循环之前初始化e
(例如e = nil
),这样变量就会在最后一行。