Ruby 组合';uniq';和';紧凑型';

Ruby 组合';uniq';和';紧凑型';,ruby,Ruby,我试图在数组中找到唯一的元素,并从中删除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?没有这种方法 我认为@array.compact.uniq和@array.uniq.compac

我试图在数组中找到唯一的元素,并从中删除
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

没有这种方法

我认为
@array.compact.uniq
@array.uniq.compact
是相等的,因为这两种方法都有O(N)复杂度

正如@Stefan提到的,使用带有
的方法可能会减少内存使用


作为一种替代方法,您可以仅使用
uniq
方法和一个块,该块返回除
nil
之外的肯定存在的元素,因此将跳过它。比如说

@array.uniq { |s| s.nil? ? @array.first : s }

但是在这种情况下,您必须确保数组的第一个元素不是
nil

否,但是您可以按照您喜欢的任何顺序附加它们,即

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

不,没有。我想
@array.compact.uniq
应该更有效。Nop。但是创建自己的;)使用bang对应项(
@array.uniq!
/
@array.compact!
)在适当的位置修改阵列应该更有效。不!我们没有:(,我有多样性
(a | a)。紧凑型
:我会尝试基准测试,尽管现实世界的结果可能取决于数据的特征-哪个更快可能取决于是否更可能存在大量重复项或大量零。它们都有O(n)时间复杂性。我很好奇:记忆复杂性呢?
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