An array method that combines "uniq" and "compact",

I am trying to find unique elements in an array and remove nil values ​​from it. My solution looks like this:

 @array = [1, 2, 1, 1, 2, 3, 4, nil, 5, nil, 5] @array.uniq.compact # => [1, 2, 3, 4, 5] 

Is there any single method that performs both operations? If not, is it effective @array.uniq.compact or @array.compact.uniq ?

+7
ruby
source share
2 answers

No, but you can add them in any order you like.

 array.uniq.compact array.compact.uniq 

As pointed out in phts, you can pass the uniq block, but I don't see that this is a very useful alternative for uniq.compact .

However, for better speed, the following may help:

 [].tap do |new_array| hash = {} original_array.each do |element| next if element.nil? || !hash[element].nil? new_array << (hash[element] = element) end end 

Finally, if speed is not an issue, and you will often use this method, then you can create your own method:

 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 
+5
source share

There is no such method.

I think that @array.compact.uniq and @array.uniq.compact are equal, because both methods have O (N) complexity.

As @Stefan mentioned, using methods with ! , you can refuse to use memory.


As an alternative way, you can only use the uniq method with a block that returns, of course, an existing element, except nil , so it will be skipped. for example

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

But in this case, you must make sure that the first element of the array is not nil .

+1
source share

All Articles