2010-10-15 14 views
5

इस पर विचार करें:तुलना वस्तुओं

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 

वहाँ अगर सभी सार्वजनिक गुण एक ही प्रकार के कक्षाओं में बराबर हैं जाँच करने के लिए कुछ रास्ता नहीं है?

उत्तर

6
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 
+0

लेकिन अगर मैं अन्य वर्गों का उपयोग करके ऐसा करना चाहता हूं तो क्या होगा? या यदि 100 विशेषताएं हैं? – dfens

+4

आपकी == (अन्य) विधि में, आप self.instance_variables.each do कर सकते हैं | ivar | self.ivar == other.ivar end आप भी === को देखना चाह सकते हैं। –

+0

मेरे लिए काम किया, धन्यवाद – dfens

8
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==, eql?, और आप के लिए hash परिभाषित करता है, ताकि दो Aaa रों, बराबर हैं यदि a और b के लिए उनके मूल्यों बराबर हैं। यह initialize को भी परिभाषित करता है ताकि ऑब्जेक्ट (Aaa.new(value_for_a, value_for_b)) बनाते समय आप वैकल्पिक रूप से a और b के मानों को पार कर सकें। और [a,b] लौटने के लिए यह to_a को परिभाषित करता है।

तुम भी एक ब्लॉक के साथ Struct.new का उपयोग अतिरिक्त पद्धतियां निर्धारित करने के कर सकते हैं, तो आप एक "सामान्य" वर्ग की पूरी शक्ति है: रूबी में वस्तुओं की तुलना होते हैं से निपटने के लिए

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

यह ठीक लगता है लेकिन मुझे वस्तुओं के लिए इस कार्यक्षमता की आवश्यकता है, वैसे भी अच्छी प्रतिक्रिया मुझे स्ट्रक्चर – dfens

+1

@dfens के बारे में नहीं पता था: वे वस्तुएं हैं। 'Struct.new' कक्षाओं के लिए सिर्फ एक कारखाना विधि है। यदि आप 'कक्षा' कीवर्ड का उपयोग करके 'आआ' को परिभाषित करेंगे और फिर '== 'आदि परिभाषित करेंगे तो आपको वही व्यवहार मिल जाएगा। – sepp2k

0

अतिरिक्त विधि hash का उपयोग करने में।

वर्ग एएए attr_accessor: एक,: ख

डीईएफ़ intialize (value_a, value_b) @a प्रदर्शन कारण से, जब वर्ग बहुत बड़ा कर रहे हैं, सबसे अच्छा hash उपयोग करने के लिए माणिक वस्तुओं के रूप में इसलिए तुलना करने के लिए है = value_a @b = value_b अंत

डीईएफ़ हैश (लक्ष्य) @ a.hash == target.a.hash & & @ b.hash == target.b.hash अंत अंत

एक = नए एएए ('जो कुछ भी', 'जब भी') बी = नए एएए ('लेकिन', 'जो कोई भी') A.hash (बी)

1

हम आसानी से उदाहरणों में से किसी भी नंबर पर सामान्यीकरण कर सकते हैं और उदाहरण चर के लिए ही टिककर खेल के लिए आवश्यकता ड्रॉप:

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 

बदलें z रहे हैं:

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

तो:

x.instance_variables.map do |v| 
    arr.map { |i| i.send(:instance_variable_get,v) }.uniq.size == 1 
end.all? 
    #=> false 
संबंधित मुद्दे