如果数组中还没有元素,则将其添加到数组中

我有一个 Ruby 类

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 = []

我想推动 MyClass#item1unique_array_of_item1,但只有当 unique_array_of_item1还没有包含那个 item1。我知道有一个简单的解决方案: 只需遍历 my_array并检查 unique_array_of_item1是否已经包含当前的 item1

还有更有效的解决方案吗?

67322 次浏览

You can use Set instead of Array.

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.

You can convert item1 to array and join them:

my_array | [item1]

@Coorasse has a good answer, though it should be:

my_array | [item]

And to update my_array in place:

my_array |= [item]

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

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)