Comparing objects in ruby

好久不见. 提交于 2020-01-01 10:07:05

问题


Consider this:

class Aaa
  attr_accessor :a, :b
end

x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2

puts x == y #=>false

Is there some way to check if all public attributes are equal in classes of same type?


回答1:


class Aaa
  attr_accessor :a, :b

  def ==(other)
    return self.a == other.a && self.b == other.b
  end
end

x = Aaa.new
x.a,x.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
y = Aaa.new
y.a,y.b = 1,2
z = Aaa.new
z.a,z.b = 1,3

x == y # => true
x == z # => false



回答2:


Aaa = Struct.new(:a, :b)

x = Aaa.new
x.a, x.b = 1,2
y = Aaa.new
y.a, y.b = 1,2

x == y #=> true

Struct defines ==, eql?, and hash for you, so that two Aaas are equal, if their values for a and b are equal. It also defines initialize so that you can optionally pass in the values for a and b when creating the object (Aaa.new(value_for_a, value_for_b)). And it defines to_a to return [a,b].

You can also use Struct.new with a block to define additional methods, so you have the full power of a "normal" class:

Aaa = Struct.new(:a, :b) do
  def c
    a+b
  end
end
Aaa.new(23,42).c #=> 65



回答3:


We can easily generalize to any number of instances and drop the requirement for getters for the instance variables:

class Aaa
  def initialize(a,b,c)
    @a, @b, @c = a, b, c
  end
end

x = Aaa.new(1,2,3)
y = Aaa.new(1,2,3)
z = Aaa.new(1,2,3)
arr = [x,y,z]

x.instance_variables.map do |v|
  arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
  #=>true

Change z to:

z = Aaa.new(1,2,4)

then:

x.instance_variables.map do |v|
  arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1
end.all?
  #=> false



回答4:


Extra method to deal with comparing objects in Ruby consists in using hash. For performance reason, when the class are huge, the best is to use hash to compare ruby objects as so :

class Aaa attr_accessor :a, :b

def intialize(value_a,value_b) @a = value_a @b = value_b end

def hash(target) @a.hash == target.a.hash && @b.hash == target.b.hash end end

A = new Aaa('whatever','whenever') B = new Aaa('however','whoever') A.hash(B)



来源:https://stackoverflow.com/questions/3941074/comparing-objects-in-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!