104

我有一个 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

有没有更有效的解决方案?

4

6 回答 6

146

@Coorasse有一个很好的答案,尽管它应该是:

my_array | [item]

my_array就地更新:

my_array |= [item]
于 2013-11-05T19:28:15.413 回答
84

您可以使用Set而不是 Array。

于 2012-12-22T16:09:42.733 回答
42

您无需my_array手动迭代。

my_array.push(item1) unless my_array.include?(item1)

编辑:

正如 Tombart 在他的评论中指出的那样,使用Array#include?效率不是很高。我想说小型阵列的性能影响可以忽略不计,但您可能希望使用Set更大的阵列。

于 2012-12-23T02:17:20.797 回答
34

您可以将 item1 转换为数组并加入它们:

my_array | [item1]
于 2013-08-20T09:04:54.860 回答
4

重要的是要记住 Set 类和 | 方法(也称为“Set Union”)将产生一个唯一元素数组,如果您不希望重复,这很好,但如果您的原始数组中设计有非唯一元素,这将是一个令人不快的惊喜。

如果您的原始数组中至少有一个您不想丢失的重复元素,那么以提前返回的方式遍历数组是最坏情况 O(n),这在总体方案中并不算太糟糕.

class Array
  def add_if_unique element
    return self if include? element
    push element
  end
end
于 2014-03-14T08:43:59.040 回答
0

我不确定这是否是完美的解决方案,但对我有用:

    host_group = Array.new if not host_group.kind_of?(Array)
    host_group.push(host)
于 2016-01-08T17:24:22.207 回答