2012-01-25 13 views
6

के साथ सरणी पर पुश सरणी कृपया मुझे यह समझाएं। मैं लूप के साथ सरणी की सरणी बनाने की कोशिश कर रहा हूं। जब यह काम नहीं करता, तो मैंने यह समझने के लिए कोड को सरल बनाने की कोशिश की कि जावास्क्रिप्ट क्या कर रहा है, लेकिन सरल कोड या तो समझ में नहीं आता है।जावास्क्रिप्ट: लूप

function test(){ 
    var sub_array = []; 
    var super_array =[]; 
    for (var i=1;i<=3;i++){ 
     sub_array.push(i); 
     super_array.push(sub_array); 
    } 
    alert(super_array); 
} 

मुझे उम्मीद है कि [1; 1,2; 1,2,3]। इसके बजाय मुझे [1,2,3; 1,2,3; 1,2,3]। यदि मैं लूप 0-2 लूप करता हूं और इंडेक्स द्वारा असाइन करता हूं तो मुझे वही घटना मिलती है।

उत्तर

6

जब आप "sub_array" दबाते हैं, तो आप प्रति कॉपी नहीं कर रहे हैं। आप "super_array" में तीन बार एक ही सरणी के साथ समाप्त होते हैं। (मैं कहना चाहिए कि आप तीन बार एक ही सरणी के लिए एक संदर्भ धक्का कर रहे हैं।)

आप ऐसा कर सकता है:

// ... 
    super_array.push(sub_array.slice(0)); 

प्रतिलिपि बनाने के लिए।

0

यह वही sub_array है जिसे आप super_array में जोड़ रहे हैं। तो यह अलग क्यों होना चाहिए।

आप एक नई सरणी नहीं बना रहे हैं और सुपर_एरे में धक्का दे रहे हैं।

13

आप हमेशा अपने सुपर-सरणी में एक ही सरणी के संदर्भ को दबा रहे हैं।

कि समस्या को हल करने के लिए, आप इसे आगे बढ़ाने से पहले उप सरणी क्लोन करने के लिए slice() उपयोग कर सकते हैं:

function test() { 
    var sub_array = []; 
    var super_array = []; 
    for (var i = 1; i <= 3; i++) { 
     sub_array.push(i); 
     super_array.push(sub_array.slice(0)); 
    } 
    alert(super_array); 
} 

संपादित करें: दान डी हक नीचे बताते हैं के रूप में, आप भी concat() तर्क के बिना कॉल कर सकते हैं slice(0) के बजाय। यह तेज है this article के अनुसार (मैं इसे अपने आप को मापने नहीं किया है):

for (var i = 1; i <= 3; i++) { 
    sub_array.push(i); 
    super_array.push(sub_array.concat()); 
} 
+2

आपने '.concat()' के बजाय ऐरे की प्रतिलिपि बनाने के लिए '.slice (0)' का उपयोग क्यों करना चुना? जो तेजी से हो सकता है लेकिन प्रोफाइलिंग मैंने किया था मुझे यकीन नहीं था। –

+0

दिलचस्प, [इस ब्लॉग] के अनुसार दिलचस्प है (http://swingpants.com/2009/03/12/fastest-way-to-copy-an-array-concat-or-slice0/) 'concat()' तेज़ है । मैं इसे अपने जवाब में जिक्र करूंगा। आपकी टिप्पणी के लिए धन्यवाद :) –

0

sub_arraysuper_array में एक संदर्भ के रूप में जमा है इसका मतलब है कि जब आप sub_array बदल परिवर्तन के अंदर super_array

1

ध्यान दें कि आप कर रहे हैं देखा जा सकता है फॉर-लूप में प्रत्येक पुनरावृत्ति के लिए एक ही सरणी को super_array में दबाकर। इसके बजाए निम्नलिखित प्रयास करें:

function test(){ 
    var sub_array = []; 
    var super_array =[]; 
    for (var i=1;i<=3;i++){ 
     sub_array = sub_array.slice(0,sub_array.length); 
     sub_array.push(i); 
     super_array.push(sub_array); 
    } 
    alert(super_array); 
} 
+0

+1 स्लाइस का उपयोग करने के लिए +1, हालांकि जब आप इसे संपूर्ण सरणी arr.slice() === arr.slice (0) क्लोन करने के लिए उपयोग कर रहे हैं, तो आपको किसी भी पैरामीटर में पास करने की आवश्यकता नहीं है arr.length) – wheresrhys

2

अच्छी तरह से। आपको समझना होगा कि ऐरे, ऑब्जेक्ट्स, फंक्शंस इत्यादि जावास्क्रिप्ट में संदर्भ हैं (केवल संख्याएं (इंट, फ्लोट्स इत्यादि) और स्ट्रिंग्स "बाय-वैल्यू" पास की जाती हैं, जिसका मतलब है कि मान कॉपी/डुप्लिकेट किया गया है)! यदि आपके पास var a=[]; है, तो var b=a कहें और b.push("bla") जोड़ें, फिर चेतावनी दें, आपको "ब्लै" प्रविष्टि दिखाएगी, भले ही आपने इसे बी में जोड़ा हो। दूसरे शब्दों में; ए और बी जावास्क्रिप्ट को मां से फ्रिज पर एक नोट की तरह कहते हैं, "बाईं ओर की सैंडविच आपके लिए है।" और फिर आप जानते हैं, कि बाएं को लेने के लिए और फ्रिज से बस कोई यादृच्छिक सैंडविच नहीं। वह आपके घर के दरवाजे पर एक और नोट (वैरिएबल बी) भी लिख सकती थी, ताकि आप जान सकें कि कहां जाना है और यदि आप जल्दी में हैं तो सैंडविच की तलाश करें। अगर वह दरवाजे पर एक सैंडविच फंस गई होगी .. ठीक है, वह अजीब होगा।और जेएस इसके बारे में सोचता है :)

तो आपकी समस्या का समाधान गिरने जैसा है;

function test(){ 
    var super_array =[]; 
    for (var i=1;i<=3;i++){ 
     var subarray=[]; 
     for (var u=1;u<=4-i;u++){ 
      sub_array.push(u); 
      super_array.push(subarray); 
     } 
    } 
    alert(super_array); 
} 

सबएरे को फिर से परिभाषित करके, आप एक नया संदर्भ बनाते हैं। ताकि परिवर्तनीय बी (घर के दरवाजे पर दूसरा नोट) अब एक अलग सैंडविच की दिशा में इंगित करता है - शायद पिताजी का सैंडविच।

मुझे आशा है कि मैं इसे समझने में आपकी सहायता कर सकता हूं।

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