2012-03-07 12 views
6

मैं एक सरणी ऐसा दिखता है जैसे है कहते हैं:रूबी में किसी सरणी के भीतर डुप्लिकेट मानों का पता कैसे लगा सकता हूं?

a = [cat, dog, cat, mouse, rat, dog, cat] 

कैसे है कि के माध्यम से मैं आते-जाते हैं, और डुप्लिकेट के साथ कुछ करना - जैसे उन्हें हटाओ?

दूसरे शब्दों में, यदि मैंने a.each do |i| किया है, तो मैं [0], [1], एक [2], एक [3] के खिलाफ [0] का मूल्यांकन कैसे करूं ... और फिर जब मुझे वह चाहिए जो मुझे चाहिए, एक [2] कहें कि इस मामले में पहला डुप्लिकेट है, फिर मैं इसे स्टैक पर दबाता हूं या इसे हटा देता हूं या कुछ।

मुझे पता है कि चाबियों का मूल्यांकन कैसे करें, बनाम मूल्य ... लेकिन मैं एक ही सरणी के भीतर एक दूसरे के खिलाफ मूल्यों का मूल्यांकन कैसे करूं?

धन्यवाद।

उत्तर

11

आपको कभी-कभी किसी भी तत्व को दोहराया है की दुकान नंबर के लिए एक हैश बना सकते हैं वापस आ जाएगी। इस प्रकार एक बार सरणी पर फिर से चलना।

h = Hash.new(0) 
['a','b','b','c'].each{ |e| h[e] += 1 } 

परिणाम चाहिए

{"a"=>1, "b"=>2, "c"=>1} 
+1

पूछा है क्यों नहीं 'h = हैश.न्यू (0)' और 'एच [ई] + = 1'? –

+0

वाक्यविन्यास का मामला। यह प्रोग्रामर विवेकाधिकार पर है। – ch4nd4n

+0

यह वास्तव में मैं क्या करने की कोशिश कर रहा था .... लेकिन ... मैं इस तरह की 'शून्य' और वृद्धि विधियों का उपयोग करने का तरीका नहीं समझ पाया। धन्यवाद! – marcamillion

1

एक सरल समाधान एक डबल पाश को चलाने के लिए है:

a.each_with_index do |a1, idx1| 
    a.each_with_index do |a2, idx2| 
    next if idx1 >= idx2 # Don't compare element to itself 
         # and don't repeat comparisons already made 

    # do something with a pair of elements (a1, a2) 
    end 
end 

तुम सिर्फ डुप्लिकेट को निकाल चाहते हैं, वहाँ एक विधि है: Array#uniq

+0

इस बारे में सोचा, लेकिन यह बहुत गन्दा लगता है। वहाँ एक और सुरुचिपूर्ण, 'रूबी-आश' समाधान है? – marcamillion

+0

डुप्लिकेट को खत्म करने के लिए, एक विधि है। सभी तत्वों को एक-दूसरे से तुलना करने के लिए, एक डबल लूप है। मैं व्यक्तिगत रूप से इसमें कोई गड़बड़ नहीं देखता हूं। यह सादा सरल कोड है जो अच्छी तरह से पढ़ता है। –

+0

सर्जीओ यह विधि अक्षम है क्योंकि आप अतीत में अनावश्यक तुलना कर रहे हैं। आपके दूसरे आंतरिक लूप को प्रत्येक लूप पर बाद में पुनरावृत्ति शुरू करना चाहिए (यानी सरणी में आगे)। – MMM

1

डुप्लिकेट को हटाने के लिए a.uniq! का उपयोग करें।

भी ruby-doc.org चेकआउट करें जहां आप रूबी के क्लास विधियों पर अधिक जानकारी प्राप्त कर सकते हैं।

+0

कॉम्पैक्ट सरणी से निकल हटा देता है। इस स्थिति में यह कैसे सहायक है? –

+0

सहमत हुए। दस्तावेज़ों को देखा और यह काम नहीं करता है। – marcamillion

+0

क्षमा करें मैं यूनिक लिखने का उल्लेख करता हूं। :) – lesce

3

इस प्रयास करें:

class Array 
    def find_dups 
     uniq.map {|v| (self - [v]).size < (self.size - 1) ? v : nil}.compact 
    end 
end 

a = ['cat', 'dog', 'cat', 'mouse', 'rat', 'dog', 'cat'] 

print a - a.find_dups # Removes duplicates 

find_dups तत्वों है कि डुप्लिकेट

5

यह कुशलता से काम करता है और नहीं बल्कि सरल है:

require 'set' 

visited = Set.new 
array.each do |element| 
    if visited.include?(element) 
    # duplicated item 
    else 
    # first appearance 
    visited << element 
    end 
end 
1

इस प्रयास करें:

 
array.inject({}){|h, e| h[e] = h[e].to_i + 1; h} 
0

यह एक सरणी में सभी डुप्लिकेट प्रिंट होगा :

array.inject(Hash.new(0)) { |hash,val| 
    hash[val] += 1; 
    hash 
}.each_pair { |val,count| 
    puts "#{val} -> #{count}" if count > 1 
} 
0

यदि आप सिर्फ डुप्लिकेट से छुटकारा पाने के लिए चाहते हैं, तो सबसे आसान काम सरणी लेना और सरणी & सरणी करना है। & ऑपरेटर का उपयोग करें।

यदि आप जानना चाहते हैं कि दोहराने वाले क्या हैं, तो सरणी & सरणी से सरणी की तुलना करें।

0

यदि सरणी क्रमबद्ध है, तो नीचे की तरह कुछ केवल डुप्लिकेट लौटाएगा।

array.sort.each_cons(2).select {|p| p[0] == p[1] }.map &:first 

सरणी को सॉर्ट करता है, फिर तत्वों के लगातार जोड़े को मानचित्र करता है, जो जोड़े समान होते हैं, तत्वों के लिए मानचित्र चुनते हैं।

0

ऐसा करने का सबसे अच्छा तरीका यह है कि इसे अपने अद्वितीय संस्करण से तुलना करें। यदि यह वही है तो इसमें कोई डुप्लिकेट नहीं है, यदि नहीं तो डुप्लिकेट मौजूद है।

unique_array = original_array.uniq 

एक अनूठा अपने सरणी के अपने मूल सरणी

if original_array == unique_array then return true else return false 

तुलना संस्करण मिलता है।

सरल!

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