2009-10-30 14 views
5

मैं इस समय एक रूबी ऐप लिख रहा हूं जो विभिन्न चीजों के लिए ट्विटर खोजने जा रहा है। जिन समस्याओं का सामना करना पड़ रहा हूं उनमें से एक को समय-समय पर निकटता में खोजों के बीच साझा परिणाम साझा किया जाता है। परिणाम ऑब्जेक्ट्स की एक सरणी में वापस आते हैं जिनमें से प्रत्येक एक ट्वीट है। मैं रूबी में Array.uniq विधि के बारे में जानता हूं जो हटाए गए सभी डुप्लिकेट के साथ एक सरणी देता है।रूबी में समान वस्तुओं को हटा रहा है?

मेरा प्रश्न यह है। क्या यूनिक विधि डुप्लिकेट को तब तक हटाती है जब तक ये ऑब्जेक्ट स्मृति में एक ही स्थान पर इंगित करते हैं या उनमें समान जानकारी होती है?

यदि पूर्व, उनकी सामग्री के आधार पर किसी सरणी से डुप्लिकेट को हटाने का सबसे अच्छा तरीका क्या है?

उत्तर

10

uniq विधि डुप्लिकेट अब तक के रूप में इन वस्तुओं स्मृति में एक ही स्थान को इंगित या वे समान जानकारी होती है कि में को दूर करता है?

विधि eql? विधि पर निर्भर करती है, इसलिए यह उन सभी तत्वों को हटा देता है जहां a.eql? (बी) सत्य लौटाता है। सटीक व्यवहार उस विशिष्ट वस्तु पर निर्भर करता है जिसके साथ आप काम कर रहे हैं।

उदाहरण के लिए, स्ट्रिंग्स को बराबर माना जाता है यदि वे समान टेक्स्ट आवंटन साझा करते हुए समान टेक्स्ट रखते हैं।

a = b = "foo" 
c = "foo" 

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

यह मूल वस्तुओं के अधिकांश भाग के लिए सच है लेकिन रूबी वस्तुओं के लिए नहीं है।

class Foo 
end 

a = Foo.new 
b = Foo.new 

a.eql? b 
# => false 

रूबी अपने वर्ग संदर्भ के आधार पर == ऑपरेटर को फिर से परिभाषित करने के लिए प्रोत्साहित।

आपके विशिष्ट मामले में मैं एक ट्विटर परिणाम का प्रतिनिधित्व करने वाली वस्तु बनाने और आपके तुलनात्मक तर्क को लागू करने का सुझाव दूंगा ताकि आप उम्मीद कर सकें कि Array.uniq व्यवहार करेगा।

class Result 

    attr_accessor :text, :notes 

    def initialize(text = nil, notes = nil) 
    self.text = text 
    self.notes = notes 
    end 

    def ==(other) 
    other.class == self.class && 
    other.text == self.text 
    end 
    alias :eql? :== 

end 

a = Result.new("first") 
b = Result.new("first") 
c = Result.new("third") 

[a, b, c].uniq 
# => [a, c] 
+0

धन्यवाद, मैंने कक्षा में आवश्यक विधि लागू की है और ऐसा लगता है कि अब यह काम कर रहा है। शुक्र है कि मुझे केवल एक चीज की तुलना करने की ज़रूरत है जो प्रत्येक ट्वीट के लिए अद्वितीय आईडी है :) मुझे लगता है कि 'other.class = self.class' 'other.class == self.class' होना चाहिए? –

+0

हाँ, आप सही हैं। फिक्स्ड। –

+1

मैं इसे 'हैश' विधि को ओवरराइट किए बिना काम करने के लिए भी नहीं मिला। देखें http://www.rabbitcreative.com/2008/01/23/comparing-custom-objects-in-ruby-using-uniq/ – spier

2

uniqeql? का उपयोग करता है, जैसा कि this thread में प्रलेखित है।

, equal?, और eql? के बीच भेद के लिए the official ruby documentation देखें।

0

मुझे विश्वास है कि Array.uniq वस्तुओं 'eql? या == विधियों, जो (यह मानते हुए वस्तुओं सामग्री के आधार पर eql? के सार्थक क्रियान्वयन प्रदान) स्मृति में अपनी तुलना कर सामग्री के आधार पर, नहीं स्थान का मतलब के माध्यम से डुप्लिकेट का पता लगाता है।

6

किसी और को इस सवाल पर ठोकर के लिए, ऐसा लगता है कि चीजों के बाद से यह सवाल पहले पूछा गया था और कुछ बदल नए रूबी संस्करणों में है की तरह (1.9.3 कम से कम), Array.uniq मानती है कि आपके वस्तु भी एक है .eql? या == के अतिरिक्त #hash विधि का सार्थक कार्यान्वयन।

संबंधित मुद्दे