我正在尝试在数组中查找唯一元素并从中删除nil
值。我的解决方案如下:
@array = [1, 2, 1, 1, 2, 3, 4, nil, 5, nil, 5]
@array.uniq.compact # => [1, 2, 3, 4, 5]
是否有任何一种方法可以同时执行这两项操作?如果没有,哪个有效,@array.uniq.compact
或@array.compact.uniq
?
答案 0 :(得分:7)
不,但您可以按照自己喜欢的顺序附加它们,即
array.uniq.compact
array.compact.uniq
正如phts所指出的,你可以将一个块传递给uniq
,但我认为这不是uniq.compact
的替代方案。
为了获得更好的速度,以下内容可能有所帮助:
[].tap do |new_array|
hash = {}
original_array.each do |element|
next if element.nil? || !hash[element].nil?
new_array << (hash[element] = element)
end
end
最后,如果速度不是问题,并且您经常使用此方法,那么您可以创建自己的方法:
class Array
def compact_uniq
self.compact.uniq
end
def compact_blank # in case you want to remove all 'blanks' as well
self.compact.reject(&:blank?)
end
end
答案 1 :(得分:2)
没有这样的方法。
我认为@array.compact.uniq
和@array.uniq.compact
是相同的,因为这两种方法都有O(N)的复杂性。
正如@Stefan提到的那样使用!
的方法可能会破坏内存使用。
作为替代方法,您可以仅使用uniq
方法和一个块,该块返回除nil
之外的肯定存在的元素,因此将跳过它。例如
@array.uniq { |s| s.nil? ? @array.first : s }
但在这种情况下,您必须确保数组的第一个元素不是nil
。