2017-07-07 6 views
12

मुझे जेएस में इस 2-आयामी सरणी के साथ कोई समस्या है। जब मैं a[1][0] बदलता हूं, a[0][0] इसके साथ परिवर्तन करता है। क्या मैं इसे शुरू करने के तरीके में कुछ गड़बड़ कर रहा हूं? यदि हां, तो मैं इसे ठीक से कैसे शुरू कर सकता हूं?सेल में किए गए परिवर्तनों को भरने के द्वारा बनाए गए इस 2 आयामी सरणी में अन्य कोशिकाओं के लिए प्रचार क्यों करें?

>var a = Array(100).fill(Array(100).fill(false)); 
>a[0][0] 
>false 
>a[1][0] 
>false 
>a[1][0] = true 
>true 
>a[1][0] 
>true 
>a[0][0] 
>true 
+3

आप याद रखना चाहिए, कि 'a.fill()' अपने तर्क का एक उदाहरण बनाता है और यह (वस्तु की तरह व्यवहार) की प्रतिलिपि नहीं है। इसलिए, 'ए' का हर तत्व एक ही सटीक वस्तु है। –

+0

यह प्रश्न एसओ पर प्रत्येक भाषा के लिए सचमुच दर्जनों बार प्रकट होता है। –

उत्तर

1

डुप्लिकेट प्रश्न की तरह ये दिखता है लेकिन मैं हमेशा सिर्फ इस

var x = new Array(10); 
for (var i = 0; i < 10; i++) { 
    x[i] = new Array(10).fill(false); 
} 
x[5][5] = true 

क्रेडिट की तरह कुछ का उपयोग किया है: How can I create a two dimensional array in JavaScript?

17
var a = Array(100).fill(Array(100).fill(false)); 

a एक सरणी में शामिल है, जो संदर्भ के प्रत्येक तत्व एक सरणी के लिए। आप बाहरी सरणी को एक सरणी के साथ भर रहे हैं जिसमें सभी झूठे मान हैं। आंतरिक सरणी केवल एक बार बनाई जा रही है और उसी सरणी के संदर्भ बाहरी सरणी के प्रत्येक तत्व को पारित किया जाता है, यही कारण है कि यदि आप एक तत्व पर एक ऑपरेशन करते हैं तो यह अन्य तत्वों पर भी प्रतिबिंबित होता है।

यह वास्तव में

var a1 = Array(100).fill(false); 
var a = Array(100).fill(a1); 

यहाँ a 100 तत्व एक ही सरणी a1 करने के लिए सभी होने संदर्भ हो जाता है के बराबर है। इसलिए यदि आप a के एक तत्व को बदलते हैं, तो सभी तत्व बदलते हैं क्योंकि वे एक ही सरणी के संदर्भ हैं।

आपको प्रत्येक तत्व को बाहरी सरणी में एक नई सरणी के साथ भरने की आवश्यकता होगी। आप कुछ इस तरह कर सकते हैं:

var a = []; 
for(var i=0; i<100; i++) 
    a.push(Array(100).fill(false)); 
3

आपकी समस्या यह है कि आप पहली सरणी के हर स्थिति में दूसरा Array(100).fill(false) का उपयोग कर रहे है। Thats क्यों जब आप "दूसरे" आयाम में एक मान बदलते हैं तो यह सरणी की प्रत्येक स्थिति में बदल जाएगा। यदि आप इससे बचना चाहते हैं तो आप प्रारंभिक की प्रत्येक स्थिति के लिए एक नया ऐरे बनाने के लिए तैयार हैं।

var x = Array(100).fill().map(x => Array(100).fill(false)); 
+0

काम नहीं करेगा। 'Map()' फ़ंक्शन एक स्पैस सरणी के अपरिभाषित गुणों पर काम नहीं करेगा। –

+0

प्रारंभिक सरणी भरने के लिए भूल गए – nicowernli

2

जो आप यहां कर रहे हैं वह बड़ी सरणी के प्रत्येक इंडेक्स पर एक ही सरणी वस्तु जोड़ रहा है।

तो जब आप

Array(x).fill(Array(y).fill(false)); 

क्या आप वास्तव में कर रहे हैं:

Array(x).fill(Y); // i.e. X.fill(Y) 

अब जब भी आप वाई बदलने के लिए, आप एक्स से प्रत्येक सूचकांक में एक ही मूल्य मिल जाएगा

डेटा को भरने के लिए आपको डेटा भरने के लिए लूप का उपयोग करना चाहिए (याद रखें कि ऐरे ऑब्जेक्ट है)।

7

आपकी संपूर्ण सरणी उसी (द्वितीय आयाम) सरणी वस्तु के संदर्भों से भरेगी।

अलग वस्तुओं के साथ इसे भरने के लिए, आप कुछ इस तरह कर दिया था:

const a = Array(100).fill(false).map(x => Array(100).fill(false)); 
 

 
a[0][0] = true; 
 

 
console.log(a[0][0]); 
 
console.log(a[0][1]); 
 
console.log(a[1][1]);

ध्यान दें कि प्रारंभिक सरणी में मानों को स्पष्ट रूप से कुछ करने के लिए सेट करने की आवश्यकता है (मेरे उदाहरण में false, लेकिन undefined भी हो सकता है), क्योंकि कन्स्ट्रक्टर द्वारा बनाई गई सरणी स्पैस है और map() फ़ंक्शन केवल उन गुणों पर काम करेगा जो वास्तव में मौजूद हैं।

कि हल करने के लिए, आप Array.from() इस्तेमाल कर सकते हैं:

const a = Array.from(Array(100), x => Array(100).fill(false)); 
 

 
a[0][0] = true; 
 

 
console.log(a[0][0]); 
 
console.log(a[0][1]); 
 
console.log(a[1][1]);

1

के बाद से सरणियों संदर्भ प्रकार के होते हैं, जे एस में एक एन आयामी सरणी बनाने इतना तुच्छ नहीं है। आपको पहले क्लोन टूल बनाना होगा।

Array.prototype.clone = function(){ 
 
    return this.map(e => Array.isArray(e) ? e.clone() : e); 
 
}; 
 

 
function arrayND(...n){ 
 
    return n.reduceRight((p,c) => c = (new Array(c)).fill().map(e => Array.isArray(p) ? p.clone() : p)); 
 
} 
 

 
var arr = arrayND(2,3,4,"x") 
 
console.log(JSON.stringify(arr));

arrayND एक आयाम का आकार तय किया पूर्णांक तर्क प्रत्येक की अनिश्चितकालीन संख्या लेता है और अंतिम तर्क भरने मूल्य है।

0

एमडीएन में वर्णित भरने का फ़ंक्शन, सभी सरणी सूचकांकों के लिए समान मान की प्रतिलिपि बनाता है। आप सरणी के क्लोन बनाने के लिए नीचे उपयोगिता का उपयोग कर सकते हैं। लेकिन चूंकि मैं स्लाइस ऑपरेटर का उपयोग कर रहा हूं, यह क्लोनिंग सरणी तक ही सीमित है।

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

if (!Array.prototype.clonefill) { 
    Object.defineProperty(Array.prototype, 'clonefill', { 
    value: function(value) { 

     // Steps 1-2. 
     if (this == null) { 
     throw new TypeError('this is null or not defined'); 
     } 

     var O = Object(this); 

     // Steps 3-5. 
     var len = O.length >>> 0; 

     // Steps 6-7. 
     var start = arguments[1]; 
     var relativeStart = start >> 0; 

     // Step 8. 
     var k = relativeStart < 0 ? 
     Math.max(len + relativeStart, 0) : 
     Math.min(relativeStart, len); 

     // Steps 9-10. 
     var end = arguments[2]; 
     var relativeEnd = end === undefined ? 
     len : end >> 0; 

     // Step 11. 
     var final = relativeEnd < 0 ? 
     Math.max(len + relativeEnd, 0) : 
     Math.min(relativeEnd, len); 

     // Step 12. 
     while (k < final) { 
     O[k] = value.slice(0); 
     k++; 
     } 

     // Step 13. 
     return O; 
    } 
    }); 
} 
Array(100).clonefill(Array(100)) 
a[0][0] = true 
a[1][0] 
false 
संबंधित मुद्दे

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