Reputation: 26008
I have a Ruby class
class MyClass
attr_writer :item1, :item2
end
my_array = get_array_of_my_class() #my_array is an array of MyClass
unique_array_of_item1 = []
I want to push MyClass#item1
to unique_array_of_item1
, but only if unique_array_of_item1
doesn't contain that item1
yet. There is a simple solution I know: just iterate through my_array
and check if unique_array_of_item1
already contains the current item1
or not.
Is there any more efficient solution?
Upvotes: 115
Views: 75355
Reputation: 3301
You can use |
(union):
my_array | [item]
And to update my_array
in place:
my_array |= [item]
Upvotes: 166
Reputation: 101
I'm not sure if it's perfect solution, but worked for me:
host_group = Array.new if not host_group.kind_of?(Array)
host_group.push(host)
Upvotes: 0
Reputation: 6266
Important to keep in mind that the Set class and the | method (also called "Set Union") will yield an array of unique elements, which is great if you want no duplicates but which will be an unpleasant surprise if you have non-unique elements in your original array by design.
If you have at least one duplicate element in your original array that you don't want to lose, iterating through the array with an early return is worst-case O(n), which isn't too bad in the grand scheme of things.
class Array
def add_if_unique element
return self if include? element
push element
end
end
Upvotes: 4
Reputation: 5528
You can convert item1 to array and join them:
my_array | [item1]
Upvotes: 36
Reputation: 3965
You don't need to iterate through my_array
by hand.
my_array.push(item1) unless my_array.include?(item1)
Edit:
As Tombart points out in his comment, using Array#include?
is not very efficient. I'd say the performance impact is negligible for small Arrays, but you might want to go with Set
for bigger ones.
Upvotes: 42