调用Array#uniq
时,新数组会保留每个副本的第一个:
["a", "b", "c", "a"].uniq #=> ["a", "b", "c"]
标准库是否为" uniq"提供了一种干净的方式。一个数组,但保持最后出现重复元素?
e.g:
["b", "c", "a"]
答案 0 :(得分:9)
您可以通过反转数组,取消它,然后再将其反转为原始顺序来实现此目的:
["a", "b", "c", "a"].reverse.uniq.reverse
#=> ["b", "c", "a"]
答案 1 :(得分:2)
这是另一种方式:
require 'set'
def reverse_uniq(arr)
s = Set.new
arr.reverse_each.with_object([]) { |e,a| a.unshift(e) if s.add?(e) }
end
例如:
reverse_uniq [1,2,3,4,3,2,1]
#=> [4, 3, 2, 1]
让我们比较大型阵列的速度方法:
require 'fruity'
require 'set'
arr = Array.new(1e6) { rand(1e5) }
compare do
re { s = Set.new; arr.reverse_each.with_object([]) { |e,a|
a.unshift(e) if s.add?(e) } }
rur { arr.reverse.uniq.reverse }
rurb { arr.reverse.uniq.reverse! }
rubrb { (arr.unshift(arr.first)).reverse.uniq!.reverse! }
rbubrb { (arr << arr[-1]).reverse!.uniq!.reverse! }
end
Running each test once. Test will take about 27 seconds.
rur is similar to rurb
rurb is similar to rubrb
rubrb is similar to rbubrb
rbubrb is faster than re by 30.000000000000004% ± 10.0%
rubrb
和rbubrb
中的第一位是为了确保:1)uniq!
在nil
时不会返回arr==arr.uniq
; 2)返回的数组元素按rur
返回的数组排序。
因此,如果内存有限,您可能希望使用rbubrb
如果您可以改变阵列,或rubrb
如果不能,则只需使用rur
。