2010-01-11 10 views
14

मेरे पास रूबी में 2-आयामी सरणी है कि मैं एक काम करने वाला डुप्लिकेट बनाना चाहता हूं। जाहिर है मैं यह नहीं कर सकता;रूबी में बहु-आयामी सरणी को डुप्लिकेट करने का कोई आसान तरीका है?

array=[[3,4],[5,9],[10,2],[11,3]] 
temp_array=array 
किसी भी संशोधन मैं temp_array को भी, सरणी का प्रयास किया जाएगा के रूप में मैं केवल ऑब्जेक्ट पहचानकर्ता की नकल की है बनाने के रूप में

। मैंने सोचा कि मैं बस इसका उपयोग करके इसे प्राप्त करने में सक्षम होगा;

temp_array=array.dup 

लेकिन जैसा कि temp_array बस वस्तु पहचानकर्ता कि दोहराया गया हो तो मैं अभी भी प्रारंभिक सरणी को संशोधित करने के अंत की एक सरणी है (अगर मैं समझता हूँ कि जब मैं इस किया था क्या गलत हुआ) यह काम नहीं करता। मैंने जो समाधान पाया वह निम्नलिखित करना था;

temp_array=[] 
array.each{|sub| temp_array << sub.dup} 

यह मेरी इच्छा को प्राप्त करता है लेकिन मेरी समस्या को हल करने का एक अजीब तरीका प्रतीत होता है।

मुझे चिंता है कि यह कैसे काम करेगा अगर मुझे नहीं पता कि मेरी सरणी क्या हो रही है (उदाहरण के लिए यदि यह संभव था कि सरणी के कुछ हिस्सों में 3-आयाम हों)। मुझे संभावित रूप से सरणी के प्रत्येक सदस्य की कक्षा का परीक्षण करना होगा ताकि यह देखने के लिए कि इसे डुप्लिकेट करने के लिए इसे फिर से चालू किया जाना है या नहीं। बिल्कुल असंभव कार्य नहीं है, लेकिन यह मेरे लिए गन्दा लगता है। क्या यह रूबी के परिणामस्वरूप बहुआयामी सरणी के लिए अंतर्निहित समर्थन की कमी है या क्या ऐसा करने के लिए एक सरल अंतर्निहित कार्य है जिसे मैंने याद किया है?

उत्तर

29

यहाँ "रूबी-esque" जिस तरह से इसे संभाल करने के लिए है:

temp_array = Marshal.load(Marshal.dump(your_array_to_be_cloned))

+3

यही तरीका है। मुझे Object.deep_copy में उस कोड को चिपकाना पसंद है। –

+0

ग्रेट, धन्यवाद। यह वास्तव में मुझे पूरी मार्शलिंग चीज भी बताता है (हालांकि मुझे जाने और वास्तव में इसके चारों ओर अपना सिर पाने के लिए कुछ और पढ़ने की ज़रूरत है)। – brad

-7

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

temp_array = array.clone 
-8

आप निर्दिष्ट here रूप array.clone उपयोग कर सकते हैं। इससे आपको मूल वस्तु की प्रतिलिपि मिल जाएगी, न केवल एक सूचक।

2

जैसा कि अन्य लोगों ने बताया है, आप क्लोन का उपयोग कर सकते हैं। यह काम नहीं करेगा, हालांकि, यह एक उथली प्रतिलिपि है, इसलिए उप सरणी (यह वास्तव में एक बहुआयामी सरणी नहीं है, मुझे लगता है) क्लोन नहीं किया जाएगा। चूंकि रूबी रूबी में उत्परिवर्तनीय वस्तुएं हैं, इसलिए उप सरणी बदल जाएंगी। उदाहरण के लिए, इसे

>> blah = [[3,5],6] 
=> [[3, 5], 6] 
>> joe = blah.clone 
=> [[3, 5], 6] 
>> joe[0] 
=> [3, 5] 
>> joe[0].push "blah" 
=> [3, 5, "blah"] 
>> blah 
=> [[3, 5, "blah"], 6] 

तो जैसा कि आप देख सकते हैं, क्लोन करने से काम नहीं करेगा। लेकिन आप जानते थे, इसलिए आपका सवाल है।

मैंने इसे अभी पकाया। यह तब तक करेगा जब तक आप असली, रूबी को ऐसा करने का तरीका नहीं ढूंढते (मैं बस रुबी में काम करता हूं, मैं एक विशेषज्ञ नहीं हूं)।

def dup_recursive(new_array, old_array) 
    old_array.each do |item| 
    if item.class == Array 
     new_array << dup_recursive([], item) 
    else 
     new_item = item.dup rescue new_item = item # in case it's got no dupe, like FixedNum 
     new_array << new_item 
    end 
    new_array 
    end 
end 

array=[[3,[9,12]],[5,9],[10,2],[11,3]] 
new_array = Array.new 
dup_recursive(new_array, array) 
puts array.inspect 
puts new_array.inspect 

मुझे पता है, मैं उपयोग कर रहा हूँ नहीं बतख टाइपिंग, लेकिन मैंने विचाराधीन वस्तु के वर्ग के लिए पूछे बिना ऐसा करने के तरीके के रूप में स्कूली किए जाने की खुशी होगी।

संपादित करें: मैं सिर्फ गूगल में गहरे क्लोन माणिक पर खोज की है चाहिए, लेकिन कभी कभी मैं कोड लिखने पसंद:) ... वैसे भी, अन्य समाधान प्रस्तुत - Marshal.load(Marshal.dump(array)) - भी Hashes के लिए काम करेंगे और इतना आगे, तो यह बेहतर तरीका है।

+0

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

+0

शायद सच है, ब्रैड, लेकिन दूसरी तरफ, शायद आपको एक बुरा नमूना मिला (लोगों का, जवाब)। समय-समय पर, प्रश्न का शब्द, या कुछ और हो सकता है। या हो सकता है कि यह मुद्दा कई रूबीवादियों द्वारा समझा नहीं जा सकता है। दुर्भाग्य से रेल की तरह ढाल आपको कुछ भी समझने से लेकर :) –

-1

सरणी के भीतर प्रत्येक उप-सरणी पर array.dup चलाने का प्रयास करें।

c = [] 
    array.each do |row| 
     c << row.dup 
    end 
0

आप इस के लिए उपयोग कर सकते हैं DeepEnumerable के deep_dup:

>> require 'deep_enumerable' 

>> array=[[3,4],[5,9],[10,2],[11,3]] 

>> temp_array=array.deep_dup 
>> array.each{|sub| sub << "XXX"} 

>> array 
=> [[3, 4, "XXX"], [5, 9, "XXX"], [10, 2, "XXX"], [11, 3, "XXX"]] 

>> temp_array 
=> [[3, 4], [5, 9], [10, 2], [11, 3]] 
2

बहुआयामी सरणी के सटीक और वास्तविक प्रतिलिपि बनाने का सबसे अच्छा तरीका है रूबी मेंहै नहीं है मार्शलिंग

Marshal.load(Marshal.dump(Name_Of_Your_Original_Array))

के कैसे ऊपर उदाहरण अर्थात

array=[[3,4],[5,9],[10,2],[11,3]] temp_array=array

का उपयोग कर इस वाक्य विन्यास का उपयोग करने के लिए देखते हैं:

यहाँमार्शलिंग की वाक्य रचना रूबी है 210

इस उदाहरण में यह केवल एक ऑब्जेक्ट बनाता है जो सरणी के समान स्मृति स्थान को इंगित करता है, यह हमारे सरणी की असली प्रति नहीं कर रहा है। यहां, यदि आप अपने temp_array के मान को संशोधित करते हैं तो यह हमारे सरणी में array चर के मूल सरणी में परिवर्तनों को स्वचालित रूप से प्रतिबिंबित करेगा। तो हम अपने मूल सरणी में स्वचालित परिवर्तनों को कैसे रोक सकते हैं, हम इसे marshalling द्वारा कर सकते हैं।

तो! कैसे हम ऐसा करते हैं, उदाहरण में हम temp_array में सरणी की एक वास्तविक प्रतिलिपि बनाने के लिए की जरूरत है।

चलो देखते हैं, ऐसा करने के तरीके:

array=[[3,4],[5,9],[10,2],[11,3]] temp_array = Marshal.load(Marshal.dump(array))

अब, हम हमारे बहुआयामी सरणी की असली कॉपी किया है, अगर आप अपने temp_array तो परिवर्तनों के किसी भी मूल्य नहीं होगा संशोधित अपने मूल array को प्रतिबिंबित करें।

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