जावास्क्रिप्ट सरणियों में नकारात्मक सूचकांक सरणी लंबाई में योगदान करना चाहिए?


84

जावास्क्रिप्ट में मैं इस तरह एक सरणी को परिभाषित करता हूं

var arr = [1,2,3];

मैं भी कर सकता हूँ

arr[-1] = 4;

अब अगर मैं

arr = undefined;

मैं गिरफ्तारी के मूल्य का संदर्भ भी खो देता हूं [-1]

मेरे लिए SO तार्किक रूप से ऐसा लगता है कि गिरफ्तारी [-1] भी गिरफ्तारी का एक हिस्सा है ।

लेकिन जब मैं निम्नलिखित करता हूं (अपरिभाषित को गिरफ्तार किए बिना)

arr.length;

यह 3 नहीं 4 लौटाता है ;

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


आप नकारात्मक सूचकांक का उपयोग क्यों करना चाहेंगे? जब तक मुझे कुछ याद नहीं आ रहा है, मुझे वह बात दिखाई नहीं दे रही है।
3

11
आप लिख भी सकते हैं arr[1.5] = 1और यह भी लंबाई को प्रभावित नहीं करता है। लंबाई को प्रभावित करने वाली भाषा विनिर्देश बहुत स्पष्ट है। आप इसे पसंद नहीं कर सकते हैं लेकिन आपको इसके साथ रहना होगा। या तो अपनी स्वयं की प्रतिस्पर्धी भाषा डिज़ाइन करें और लोगों को इसे स्विच करने के लिए मनाएं।
रेमंड चेन

1
@DigvijayYadav: जावास्क्रिप्ट में कई अन्य चीजों की तरह एक दोष या एक विशेषता माना जा सकता है। ऐसा इसलिए है क्योंकि सरणियाँ वस्तुओं की तरह थोड़ा व्यवहार करती हैं, आप एक स्ट्रिंग का उपयोग भी कर सकते हैं var a = []; a['foo'] = 'baz'लेकिन इसका मतलब यह नहीं है कि आपको चाहिए; यह सभी सम्मेलनों के खिलाफ स्पष्ट रूप से है।
एलक्लेनर्स

2
दोस्तों, यहाँ मुख्य बात यह है कि ARRAYS OBJECTS हैं। इसमें कोई फर्क नही है। यही इस व्यवहार का कारण है, और यह पूरी तरह से जानबूझकर है भले ही आप इसे पसंद न करें। बस तब तक प्रतीक्षा करें जब तक आप यह न सीख लें कि सभी संख्याओं को फ्लोटिंग पॉइंट, यहां तक ​​कि पूर्णांक के रूप में दर्शाया गया है। जावास्क्रिप्ट एक जिज्ञासु भाषा है ...
टोनी आर

2
आप उस एल्गोरिथ्म का विवरण पा सकते हैं जो विनिर्देशन में सरणी तत्वों की सेटिंग को परिभाषित करता है: es5.github.com/#x15.4.5.1.(espatically चरण 4) और "सरणी सूचकांक" यहां परिभाषित किया गया है: es5.github.com /#x15.4
फेलिक्स क्लिंग

जवाबों:


109

मेरे लिए SO तार्किक रूप से ऐसा लगता है कि गिरफ्तारी [-1] भी गिरफ्तारी का एक हिस्सा है।

हां यह है, लेकिन उस तरीके से नहीं जैसा आप सोचते हैं।

आप किसी सरणी (जैसे जावास्क्रिप्ट में किसी भी अन्य ऑब्जेक्ट की तरह) के लिए मनमाने ढंग से गुण असाइन कर सकते हैं, जो कि आप कर रहे हैं जब आप सरणी को "इंडेक्स" करते हैं -1और एक मूल्य निर्दिष्ट करते हैं। चूंकि यह सरणी का सदस्य नहीं है और सिर्फ एक मनमानी संपत्ति है, इसलिए आपको lengthउस संपत्ति पर विचार करने की उम्मीद नहीं करनी चाहिए ।

दूसरे शब्दों में, निम्नलिखित कोड समान कार्य करता है:

var arr = [1, 2, 3];

​arr.cookies = 4;

alert(arr.length) // 3;

31
ठीक है, इसका मतलब है कि नकारात्मक सूचकांक वास्तव में वास्तविक अनुक्रमित की तरह काम नहीं करते हैं।
me_digvijay

4
सही, वे सरणी पर सिर्फ मनमानी गुण हैं।
एंड्रयू व्हाइटेकर

लेकिन क्या होगा अगर मैं पॉजिटिव इंडेक्स का उपयोग करना चाहता हूं, जैसे कि इंडेक्स जैसे गुण नहीं हैं और मैं नहीं चाहता कि वे सरणी लंबाई में योगदान दें?
me_digvijay

7
फिर एक सरणी का उपयोग न करें, एक सादे ol 'ऑब्जेक्ट का उपयोग करें। लेकिन उस स्थिति में आप अंतर्निहित lengthसंपत्ति खो देंगे ।
एंड्रयू व्हाइटेकर

2
@ दिग्विजय: कंसोल केवल सकारात्मक पूर्णांक नामों के साथ गुणों को दिखाता है क्योंकि (मुझे लगता है) यह सिर्फ एक साधारण forलूप से 0करता है .lengthconsole.dir(arr)पूरी वस्तु देखने के लिए करें । इसके अलावा, सरणियों तक पहुँचने के लिए ब्रैकेट नोटेशन का उपयोग करना सरणियों की विशेषता नहीं है, यह वस्तुओं की अंतर्निहित विशेषता है ( var obj = {foo: 'bar'}; obj.foo or obj['foo'])।
फेलिक्स क्लिंग

25

lengthसंपत्ति एक नंबर एक उच्चतम सौंपा "अनुक्रमणिका", जहाँ सरणी "अनुक्रमणिका" इससे अधिक पूर्णांक हैं या शून्य के बराबर की तुलना में अधिक वापस आ जाएगी। ध्यान दें कि JS "विरल" सरणियों की अनुमति देता है:

var someArray = [];
someArray[10] = "whatever";
console.log(someArray.length); // "11"

बेशक अगर कोई तत्व नहीं हैं तो lengthहै 0। ध्यान दें कि lengthयदि आप deleteउच्चतम तत्व को निकालने के लिए उपयोग करते हैं तो अपडेट नहीं होता है।

लेकिन सरणियाँ ऑब्जेक्ट्स हैं, इसलिए आप अन्य मनमानी संपत्ति नामों के साथ गुणों को असाइन कर सकते हैं जिनमें नकारात्मक संख्याएं या भिन्न शामिल हैं:

someArray[-1] = "A property";
someArray[3.1415] = "Vaguely Pi";
someArray["test"] = "Whatever";

ध्यान दें कि पर्दे के पीछे जेएस एक नंबर की आपूर्ति करते हुए भी संपत्ति के नाम को तार में बदल देता है -1। (सकारात्मक पूर्णांक अनुक्रमणिका भी तार बन जाती है, उस बात के लिए।)

सरणी विधियां, जैसे .pop(), .slice()आदि, केवल शून्य-या उच्चतर पूर्णांक "अनुक्रमित" पर काम करती हैं, अन्य गुणों पर नहीं, इसलिए lengthउस बिंदु पर संगत है।


धन्यवाद आपके उत्तर ने बहुत मदद की। इसके अलावा, मैंने नकारात्मक सूचकांक के साथ ब्याह विधि की कोशिश की, मैंने पाया कि अगर मैं -1 का उपयोग करता हूं तो यह सरणी के अंतिम तत्व पर जाता है, -2 के लिए दूसरा अंतिम तत्व और इसी तरह जाता है।
me_digvijay

+1। लंबाई आपको यह नहीं बताती है कि कितने तत्व हैं, या कितने गुण हैं। यह सिर्फ उच्चतम सूचकांक है। 1. उदाहरण के लिए var a = new Array(9), aइसकी लंबाई 9 है और इसमें कोई तत्व नहीं है।
रॉब

1
@ दिग्विजयवाद - हाँ, Array.slice()विधि ऐसा करने वाली है। String.slice()विधि एक ही बात करता है।
nnnnnn

7

ध्यान दें कि जब आप किसी स्थिति (या 0) सूचकांक का उपयोग करते हैं, तो मान सरणी के भीतर रखे जाते हैं:

var array = [];

array[0] = "Foo";
array[1] = "Bar";

// Result: ["Foo", "Bar"]
// Length: 2

जब आप गैर-इंडेक्स मान जोड़ते हैं तो ऐसा नहीं होता (0-9 + नहीं):

var array = [];

array[0]  = "Foo";
array[1]  = "Bar";
array[-1] = "Fizzbuzz"; // Not a proper array index - kill it

// Result: ["Foo", "Bar"]
// Length: 2

जब आप नियमों द्वारा खेलते हैं तो मान केवल सरणी में रखे जाते हैं। जब आप नहीं करते हैं, तो उन्हें स्वीकार नहीं किया जाता है। हालाँकि, उन्हें Array ऑब्जेक्ट पर ही स्वीकार किया जाता है, जो कि जावास्क्रिप्ट में किसी भी चीज़ के बारे में है। भले ही ["Foo", "Bar"]हमारे सरणी में एकमात्र मान हैं, फिर भी हम पहुंच सकते हैं "Fizzbuzz":

array[-1]; // "Fizzbuzz"

लेकिन फिर से ध्यान दें कि यह सरणी मानों का हिस्सा नहीं है, क्योंकि इसका "सूचकांक" मान्य नहीं है। इसके बजाय इसे केवल दूसरे सदस्य के रूप में सरणी पर जोड़ा गया था। हम एक ही अंदाज में अन्य सरणी सदस्यों तक पहुँच सकते हैं:

array["pop"]; // function pop() { [native code] }

यहां ध्यान दें कि हम popएरे पर विधि का उपयोग कर रहे हैं , जो हमें सूचित करता है कि इसमें मूल कोड शामिल है। हम किसी भी सरणी मान को "पॉप" की कुंजी के साथ एक्सेस नहीं कर रहे हैं, बल्कि सरणी ऑब्जेक्ट पर ही एक सदस्य हैं। हम वस्तु के सार्वजनिक सदस्यों पर साइकिल चलाकर इसकी पुष्टि कर सकते हैं:

for (var prop in array) 
    console.log(prop, array[prop]);

निम्नलिखित में से कौन सा थूक है:

 0 Foo
 1 Bar
-1 Fizzbuzz

तो फिर, यह पर वस्तु है, लेकिन यह नहीं है में सरणी

बहुत बढ़िया सवाल! मुझे यकीन है कि एक डबल लेने के लिए कारण बना।


1
+1 यहां तक ​​कि विनिर्देश बताता है कि एक सकारात्मक संख्यात्मक संपत्ति नाम वाले गुणों को सरणी के तत्व कहा जाता है (और कोई भी अन्य संपत्ति नहीं है): es5.github.com/#x15.4
फेलिक्स क्लिंग

परिणाम नहीं है: ["Foo", "Bar"]लेकिन यहाँ फ़िडेल की["Foo", "Bar", -1: "Fizzbuzz"] जाँच करें । जैसा आपने लिखा है यह कुंजी -1 के साथ एक संपत्ति बन जाता है, लेकिन यह निश्चित रूप से आउटपुट में दिखाई देता है। अन्यथा आपका उत्तर अच्छा और पूर्ण है। यदि आप बदलते हैं तो मैं फिर से उठूंगा, मेरा पतन कठोर था, लेकिन इसे दूर नहीं कर सकता; समय समाप्त।
विल्ट

5

यदि आप वास्तव में नकारात्मक इंडेक्स और अन्य इंडेक्स को लंबाई में शामिल करना चाहते हैं, तो स्वयं कार्यक्षमता बनाएं:

function getExtendedArray() {
    var a = [];

    Object.defineProperty(a, 'totalLength', { 
        get : function() { return Object.keys(a).length; }
    });

    return a;
}

फिर उदाहरण के लिए:

var myArray = getExtendedArray();
console.log(myArray.totalLength); // 0
myArray.push("asdf");
myArray[-2] = "some string";
myArray[1.7777] = "other string";
console.log(myArray.totalLength); // 3

और यदि आप चाहते हैं कि लंबाई में केवल गिने हुए सूचकांक / गुण शामिल हों तो आप कुंजी के लिए एक स्टेटमेंट जोड़ सकते हैं - if(Number(key) != NaN) length++;यदि आप फ्लोट को फ़िल्टर करना चाहते हैं && key % 1 == 0तो इस स्थिति में जोड़ें
बोनविले

4

JS में Array एक विशेष प्रकार की Object है। एक विशेष वाक्यविन्यास है, जो अच्छा है, क्योंकि यह हमें उनके साथ प्रभावी ढंग से काम करने की अनुमति देता है। कल्पना कीजिए कि एक सरणी को इस तरह लिखना कितना कठिन होगा:

const array = {0: 'foo', 1: 'bar', 2: 'baz'} //etc...

लेकिन वे अभी भी वस्तुएं हैं । तो अगर तुम करते हो:

const myArray = [42, 'foo', 'bar', 'baz'];

myArray[-1] = 'I am not here';
myArray['whatever'] = 'Hello World';

वे गैर-पूर्णांक गुण किसी ऑब्जेक्ट से जुड़े होंगे (जो कि सरणी है), लेकिन कुछ देशी तरीकों की तरह सुलभ नहीं हैं Array.length

आप मान सकते हैं कि देसी 'लंबाई' विधि एक गेटर जो सभी गुण गिना जाता है (और अनुक्रमित रहे हैं , जबकि मूल्यों वास्तविक हैं, गुण मान ) धनात्मक पूर्णांक या शून्य करने के लिए परिवर्तनीय। इस छद्म कार्यान्वयन जैसा कुछ:

के कारण चश्मा , देशी lengthविधि - एक के रूप में गेटर ( exampleArray.length) - सभी 'ग़ैर-ऋणात्मक पूर्णांक कम 2 से जाँच करेगा 32 ' चाबियाँ, सबसे बड़ी एक हो और उसके संख्यात्मक मान +1 लौट आते हैं।

एक सेटर ( exampleArray.length = 42) के रूप में, यह या तो 'गुम' सूचकांकों के लिए कुछ खाली स्लॉट्स बनाएगा, यदि दी गई लंबाई वास्तविक संख्या में nonnegative पूर्णांक कुंजियों की तुलना में अधिक है, या सभी nonnegative पूर्णांक कुंजियों (और उनके मूल्यों) को हटा दें जो तब अधिक नहीं है लंबाई दी गई।

छद्म कार्यान्वयन:

const myArray = {
  '-1': 'I am not here', // I have to use apostrophes to avoid syntax error
  0: 42,
  1: 'foo',
  2: 'bar',
  3: 'baz',
  whatever: 'Hello World',

  get myLength() {
    let highestIndex = -1;
    for (let key in this) {
      let toInt = parseInt(key, 10);
      if (!Number.isNaN(toInt) && toInt > -1) {
        // If you're not an integer, that's not your business! Back off!
        if (toInt > highestIndex) highestIndex = toInt;
      }
    }
    return highestIndex + 1;
  },
  set myLength(newLength) {
    /* This setter would either:
      1) create some empty slots for 'missing' indices if the given length is greater than the actual number of non-negative-integer keys
      2) delete all non-negative-integer keys (and their values) which are not greater then the given length.
    */
  }
}

console.log(myArray.myLength); // 4

myArray[9] = 'foobar';

console.log(myArray.myLength); // 10


3

जावास्क्रिप्ट में सरणी वास्तव में वस्तुएं हैं। वे केवल ऐरे कंस्ट्रक्टर के प्रोटोटाइप हैं।

ऐरे सूचकांक वास्तव में एक हैशमैप में चाबियाँ हैं, और सभी चाबियाँ स्ट्रिंग्स में परिवर्तित हो जाती हैं। आप कोई भी कुंजी बना सकते हैं (अर्थात "-1"), लेकिन एरे पर दिए गए तरीके एक सरणी की तरह कार्य करने के लिए तैयार किए गए हैं। तो lengthवस्तु का आकार नहीं है, यह केवल सबसे बड़ा पूर्णांक सूचकांक से बड़ा होने की गारंटी है। इसी तरह, मुद्रण arrकेवल पूर्णांक कुंजियों के साथ मूल्यों को सूचीबद्ध करेगा> = 0।

अधिक जानकारी यहाँ।


बिल्कुल सही। या हम यह सोचना शुरू कर सकते हैं कि सरणी ['foo'] एक वैध सूचकांक क्यों नहीं है - जावास्क्रिप्ट आपको इसे करने की अनुमति देता है, लेकिन इसका मतलब यह नहीं है कि एक सरणी (और इसके तत्व) की परिभाषा एक भाषा से दूसरी भाषा में बदल जाती है। इरादा के अनुसार काम करना।
जुड़वां एयरबॉल

वास्तव में "सरणियाँ" जेएस में मौजूद नहीं हैं। लेकिन "साहचर्य सरणियों," को "ऑब्जेक्ट्स" के रूप में भी जाना जाता है, जेएस के मूल में हैं। इसलिए यह ऐरे ऑब्जेक्ट बनाने के लिए एक बड़ी छलांग नहीं थी जो एक नियमित सरणी की नकल करता है।
टोनी आर

1
सरणियों और सादे वस्तुओं के बीच एक बहुत ही विशेष अंतर है: स्व-समायोजन लंबाई संपत्ति।
रोबग

1

एमडीएन के अनुसार:

लंबाई की संपत्ति का मूल्य एक धनात्मक चिह्न है और 2 से 32 शक्ति (232) से कम का मान है।

जावास्क्रिप्ट में आप अपने द्वारा बनाई गई किसी भी वस्तु पर एक संपत्ति निर्धारित कर सकते हैं।

var array = new Array();
array = [1,2,3];
array["boom"] = "pow";

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

array[-1] = "property does not add to array length";

यही कारण है कि लंबाई इसे प्रतिबिंबित नहीं करती है, लेकिन for..in लूप इसे दिखाता है।


-1

जब आप गैर-पॉजिटिव या नॉन न्यूमेरिक इंडेक्स का उपयोग करते हैं तो ऐरे एक ऐररेटिव ऐरे के रूप में व्यवहार करता है जिसमें की-वैल्यू पेयर होता है।

सरणी के माध्यम से पुनरावृत्त करने के लिए आप उपयोग कर सकते हैं

for(var index in myArray) {
  document.write( index + " : " + myArray[index] + "<br />");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.