8

こんにちは、

私は Ruby (1.8.6 を使用) にかなり慣れていないので、次の機能が自動的に利用可能かどうかを知る必要があります。

私は車のクラスを持っています。そして2つのオブジェクトがあります:

car_a and car_b

オブジェクトの 1 つで他のオブジェクトと比較してどのプロパティが異なるかを比較して見つける方法はありますか?

例えば、

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'

それから

car_a.compare_with(car_b)

私に与えるべきです:

{:color => 'Blue', :sun_roof => 'false'}

またはその趣旨の何か?

4

4 に答える 4

7

微調整が必​​要ですが、基本的な考え方は次のとおりです。

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)
于 2009-10-30T08:06:15.130 に答える
2

どうですか

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}
于 2009-10-30T08:45:31.417 に答える
0

私は同じ問題を抱えていて、あなたの解決策のいくつかを見ていましたが、Ruby にはこれを解決する方法が必要だと考えました。ActiveModel::Dirty を発見しました。魅力のように機能します。

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes

于 2012-11-15T23:20:36.010 に答える
0

プロパティの違いをすぐに取得できるかどうかはわかりません。しかし、回避策は.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 ==

違いがある場合は、オブジェクト クラスの To_Array メソッドを次のように使用できます。

car_a.to_a
car_b.to_a

2つの配列の違いを比較するのは簡単です。

テストしていませんが、

(car_a | car_b ) - ( car_a & car_b )

またはそのようなものは、プロパティの違いを与えるはずです。

HTH

于 2009-10-30T08:00:00.813 に答える