2010-07-15 12 views
57

मेरे पास एक सरणी है जिसे मैं पुन: सक्रिय करना चाहता हूं और कुछ तत्वों को हटा देना चाहता हूं। यह काम नहीं करता:सरणी पर पुनरावृत्ति करते समय मैं ऐरे # हटा कैसे उपयोग कर सकता हूं?

a = [1, 2, 3, 4, 5] 
a.each do |x| 
    next if x < 3 
    a.delete x 
    # do something with x 
end 
a #=> [1, 2, 4] 

मैं a चाहते [1, 2] किया जाना है। मैं इसके पास कैसे आ सकता हूं?

+0

संभावित डुप्लिकेट [रूबी में इटरेटिंग करते समय हटाना?] (Http://stackoverflow.com/questions/2933366/deleting-while-iterating-in-ruby) – sschuberth

उत्तर

101

a.delete_if { |x| x >= 3 }

देखें विधि दस्तावेज़ here

अद्यतन:

आप ब्लॉक में एक्स संभाल कर सकते हैं:

a.delete_if do |element| 
    if element >= 3 
    do_something_with(element) 
    true # Make sure the if statement returns true, so it gets marked for deletion 
    end 
end 
+1

मुझे यह होने पर 'x' के साथ कुछ करने की ज़रूरत है नष्ट कर दिया। क्या मुझे इसे ब्लॉक में रखना चाहिए? – Adrian

+0

हां, मेरा अद्यतन उत्तर – Chubas

+1

@ एड्रियन देखें या आप 'अस्वीकार' का उपयोग कर सकते हैं। –

2

मैं लंबे समय तक नहीं पहले यह सवाल पूछा था।

Deleting While Iterating in Ruby?

यह काम नहीं कर रहा है क्योंकि रूबी .each पाश बाहर निकलता है जब कुछ को हटाने का प्रयास। यदि आप बस सरणी से चीजों को हटाना चाहते हैं, delete_if काम करेगा, लेकिन यदि आप अधिक नियंत्रण चाहते हैं, तो मेरे पास उस थ्रेड में समाधान है, हालांकि यह बदसूरत है।

+8

विलोपन लूप को तोड़ता नहीं है। सूचकांक का उपयोग करके प्रत्येक 'प्रभावी ढंग से पुनरावृत्त होता है। इसलिए यदि आप हटाते हैं, तो इंडेक्स अलग होते हैं, और अगला पुनरावृत्ति नई अनुक्रमणिका का उपयोग करेगा। इसे आज़माएं: 'arr = [1,2,3,4,5,6]; arr.each_with_index {| ई, i | पी [एआर, ई, मैं]; अगली अगर ई <3; arr.delete e} '। जब आइटम 3 तक पहुंच जाता है, तो सूचकांक 2 होता है। 3 हटा दिए जाने के बाद, अगला पुनरावृत्ति सूचकांक में 3 तक बढ़ता है, और आइटम 5 है। तो 4 छोड़ दिया जाता है। 6 उसी कारण से छोड़ा गया है। – Kelvin

7

आप सरणी से नष्ट करने के लिए की जरूरत नहीं है, आप इसे इतना फ़िल्टर कर सकते हैं:

a = [1, 2, 3, 4, 5] 

b = a.select {|x| x < 3} 

puts b.inspect # => [1,2] 

b.each {|i| puts i} # do something to each here 
+0

ज़ोंबी पोस्ट को बढ़ाने के लिए खेद है, लेकिन यह जानकर उत्सुक है कि बी = एक दृष्टिकोण का सबसेट मेमोरी उपयोग बढ़ाता है या क्या यह आंतरिक पॉइंटर्स या मूल आइटम को संदर्भित करने के लिए कुछ उपयोग करता है? कारण मैं पूछता हूं कि मेरा उपयोग मामला काफी स्मृति संवेदनशील है, इस बारे में उत्सुक है कि मूल सरणी या चयन से हटाना एक बेहतर तरीका है ... – gorlaz

2

यह reject! उपयोग कर रहा है क्या करने के लिए एक और तरीका है, जो यकीनन स्पष्ट है क्योंकि यह एक ! जो "इसका मतलब यह है है सरणी बदल जाएगा "। केवल अंतर यह है कि reject! कोई बदलाव नहीं किए जाने पर nil वापस कर देगा।

a.delete_if {|x| x >= 3 } 

या

a.reject! {|x| x >= 3 } 

दोनों काम ठीक होगा।

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