Helo,
I am pretty new to Ruby (using 1.8.6) and need to know whether the following functionality is available automatically and if not, which would be the best method to implement it.
我是Ruby的新手(使用1.8.6)并且需要知道以下功能是否可以自动使用,如果没有,这将是实现它的最佳方法。
I have class Car. And have two objects:
我有班车。并有两个对象:
car_a and car_b
Is there any way I could do a compare and find what properties differ in one of the objects as compared to the other one?
有什么办法可以比较一下,找出其中一个对象与另一个对象有什么不同?
For example,
car_a.color = 'Red'
car_a.sun_roof = true
car_a.wheels = 'Bridgestone'
car_b.color = 'Blue'
car_b.sun_roof = false
car_b.wheels = 'Bridgestone'
then doing a
然后做一个
car_a.compare_with(car_b)
should give me:
应该给我:
{:color => 'Blue', :sun_roof => 'false'}
or something to that effect?
或者那种效果?
4 个解决方案
#1
7
needs some tweaking, but here's the basic idea:
需要一些调整,但这是基本的想法:
module CompareIV
def compare(other)
h = {}
self.instance_variables.each do |iv|
print iv
a, b = self.instance_variable_get(iv), other.instance_variable_get(iv)
h[iv] = b if a != b
end
return h
end
end
class A
include CompareIV
attr_accessor :foo, :bar, :baz
def initialize(foo, bar, baz)
@foo = foo
@bar = bar
@baz = baz
end
end
a = A.new(foo = 1, bar = 2, baz = 3)
b = A.new(foo = 1, bar = 3, baz = 4)
p a.compare(b)
#2
2
How about
class Object
def instance_variables_compare(o)
Hash[*self.instance_variables.map {|v|
self.instance_variable_get(v)==o.instance_variable_get(v) ? [] : [v,o.instance_variable_get(v)]}.flatten]
end
end
>> car_a.instance_variables_compare(car_b)
=> {"@color"=>"Blue", "@sun_roof"=>false}
#3
0
Not sure if getting the difference of properties straight away is possible. But the work around would be to try the .eql? operator on both the objects
不确定是否可以立即获得属性的差异。但是,解决方法是尝试.eql?两个对象上的运算符
#for example,
car_a.eql?(car_b)
#could test whether car_a and car_b have the same color, sunroof and wheels
#need to override this method in the Car class to be meaningful,otherwise it's the same as ==
If there is a difference then you could use the Object Class's To_Array method like
如果存在差异,那么您可以使用Object Class的To_Array方法
car_a.to_a
car_b.to_a
now comparing 2 arrays for difference would be easy.
现在比较两个阵列的差异将很容易。
Not tested but
没有测试但是
(car_a | car_b ) - ( car_a & car_b )
or something like that should give you the difference in properties.
或类似的东西应该给你的属性差异。
HTH
#4
0
I had the same issue and was looking at some of your solutions, but I figured Ruby had to have a way to solve this. I discovered ActiveModel::Dirty. Works like a charm.
我遇到了同样的问题并且正在研究你的一些解决方案,但我认为Ruby必须有办法解决这个问题。我发现了ActiveModel :: Dirty。奇迹般有效。
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes
#1
7
needs some tweaking, but here's the basic idea:
需要一些调整,但这是基本的想法:
module CompareIV
def compare(other)
h = {}
self.instance_variables.each do |iv|
print iv
a, b = self.instance_variable_get(iv), other.instance_variable_get(iv)
h[iv] = b if a != b
end
return h
end
end
class A
include CompareIV
attr_accessor :foo, :bar, :baz
def initialize(foo, bar, baz)
@foo = foo
@bar = bar
@baz = baz
end
end
a = A.new(foo = 1, bar = 2, baz = 3)
b = A.new(foo = 1, bar = 3, baz = 4)
p a.compare(b)
#2
2
How about
class Object
def instance_variables_compare(o)
Hash[*self.instance_variables.map {|v|
self.instance_variable_get(v)==o.instance_variable_get(v) ? [] : [v,o.instance_variable_get(v)]}.flatten]
end
end
>> car_a.instance_variables_compare(car_b)
=> {"@color"=>"Blue", "@sun_roof"=>false}
#3
0
Not sure if getting the difference of properties straight away is possible. But the work around would be to try the .eql? operator on both the objects
不确定是否可以立即获得属性的差异。但是,解决方法是尝试.eql?两个对象上的运算符
#for example,
car_a.eql?(car_b)
#could test whether car_a and car_b have the same color, sunroof and wheels
#need to override this method in the Car class to be meaningful,otherwise it's the same as ==
If there is a difference then you could use the Object Class's To_Array method like
如果存在差异,那么您可以使用Object Class的To_Array方法
car_a.to_a
car_b.to_a
now comparing 2 arrays for difference would be easy.
现在比较两个阵列的差异将很容易。
Not tested but
没有测试但是
(car_a | car_b ) - ( car_a & car_b )
or something like that should give you the difference in properties.
或类似的东西应该给你的属性差异。
HTH
#4
0
I had the same issue and was looking at some of your solutions, but I figured Ruby had to have a way to solve this. I discovered ActiveModel::Dirty. Works like a charm.
我遇到了同样的问题并且正在研究你的一些解决方案,但我认为Ruby必须有办法解决这个问题。我发现了ActiveModel :: Dirty。奇迹般有效。
http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes