删除对象数组中的重复项

时间:2017-02-16 17:23:27

标签: ruby

如何删除对象数组中的重复对象。 例如:

 [#< @a:1, @b:2>, #< @a:3, @b:3>, #<@a:3, @b:3>] => [ #< @a:1, @b:2>, #< @a:3, @b:3>]. 

另外我的理解是没有两个对象可以是相同的......如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:3)

您可以使用Array#uniq,但是您需要对您的班级进行一些小改动。每the docsuniq&#34;使用hasheql?方法比较值,以提高效率,&#34;因此,您需要定义hasheql?,以便将类的两个对象标识为重复项。例如,如果具有相同ab属性的两个对象重复,则可以执行以下操作:

class Foo
  attr_reader :a, :b

  def initialize(a, b)
    @a, @b = a, b
  end

  def hash
    [ a, b ].hash
  end

  def eql?(other)
    hash == other.hash
  end
end

arr = [ Foo.new(1, 2), Foo.new(3, 3), Foo.new(3, 3) ]
p arr.uniq
# => [#<Foo:0x007f686ac36700 @a=1, @b=2>, #<Foo:0x007f686ac366b0 @a=3, @b=3>]

或者,如果您不想或不能定义hasheql?方法,则可以使用uniq的阻止形式:

class Bar
  attr_reader :a, :b

  def initialize(a, b)
    @a, @b = a, b
  end
end

arr2 = [ Bar.new(1, 2), Bar.new(3, 3), Foo.new(3, 3) ]

p arr2.uniq {|obj| [ obj.a, obj.b ] }
# => [#<Bar:0x007fe80f7b6750 @a=1, @b=2>, #<Bar:0x007fe80f7b6700 @a=3, @b=3>]

您可以在repl.it上看到both of these

答案 1 :(得分:0)

使用Array#uniq。来自文档的示例:

a = [ "a", "a", "b", "b", "c" ]
a.uniq 
# => ["a", "b", "c"]

请注意,此方法使用其hasheql?方法来识别重复项。这就是说:如果uniq无法正常工作,那么您可能会确保hasheql?得到恰当的实施。