पर्ल में एक सरणी का आकार ज्ञात करें


243

मुझे लगता है कि एक सरणी का आकार खोजने के लिए कई अलग-अलग तरीके हैं। इन तीन विधियों में क्या अंतर है?

my @arr = (2);
print scalar @arr; # First way to print array size

print $#arr; # Second way to print array size

my $arrSize = @arr;
print $arrSize; # Third way to print array size

13
अन्य तरीकों: print 0+@arr, print "".@arr,print ~~@arr
भीड़

3
@ मब, हम, से बचना चाहते हैं "".@arrक्योंकि "@arr"कुछ अलग हो सकता है।
इकेगामी

39
"दूसरा तरीका" सरणी आकार को मुद्रित करने का एक तरीका नहीं है ...
tadmc

स्केलर संदर्भ में; @ तालिका तालिका का आकार लौटाता है। $ x = @ गिरफ्तारी अदिश संदर्भ है। $ # गिरफ्तारी सरणी का अंतिम सूचकांक है। इंडेक्सिंग 0 से शुरू हो रही है, फिर सही समीकरण है $ # गिरफ्तारी + 1 == @ वर्ष। यदि आप कुछ तत्व ऑर्डर से बाहर लिखते हैं, उदाहरण के लिए $ गिरफ्तारी [100] = 'कोई', तो तालिका स्वचालित रूप से अधिकतम इंडेक्स 100 तक बढ़ जाती है, और (इंडेक्स 0 सहित) 101 तत्वों तक।
ज़नीक

जवाबों:


234

पहले और तीसरे तरीके समान हैं: वे स्केलर संदर्भ में एक सरणी का मूल्यांकन करते हैं। मैं इसे सरणी का आकार प्राप्त करने का मानक तरीका मानूंगा।

दूसरा तरीका वास्तव में सरणी के अंतिम सूचकांक को लौटाता है, जो कि (आमतौर पर) सरणी आकार के समान नहीं है।


29
(1,2,3) का आकार 3 है, और अनुक्रमित हैं (डिफ़ॉल्ट रूप से) 0, 1 और 2. इसलिए, $ # गिरफ्तारी इस मामले में 2 होगी, न कि 3.
नैट सीके

5
पूर्वनिर्धारित चर $[निर्दिष्ट करता है "एक सरणी में पहले तत्व का सूचकांक, और एक विकल्प में पहला चरित्र" ( perldoc perlvar)। यह डिफ़ॉल्ट रूप से 0 पर सेट है, और इसे 0 के अलावा किसी अन्य चीज़ पर सेट करना अत्यधिक हतोत्साहित करता है।
कीथ थॉम्पसन

5
@ कीथ थॉम्पसन, $[हतोत्साहित किया गया है (और एक दशक से है)। $[पदावनत किया गया है। $[चेतावनियों को चालू न करने पर भी अविकसित चेतावनी के मुद्दों का उपयोग करना । कुछ भी लेकिन शून्य से असाइन करना $[5.16 में एक त्रुटि होगी। क्या हम $[पहले से ही उल्लेख करना बंद कर सकते हैं ?
इकेगामी

2
@ कीथ थॉम्पसन, वास्तव में 5.14 से अधिक पुराना है। लेकिन जैसा मैंने कहा, यह उससे कहीं अधिक समय के लिए हतोत्साहित और पदच्युत है, और $[इसका उपयोग करने वाले को इसके प्रभावों का पता चल जाएगा।
इकेगामी

7
@ ईकगामी: हाँ, लेकिन किसी के बीच अंतर को समझने की कोशिश करनी चाहिए scalar @arrऔर अभी भी दुर्लभ के संभावित प्रभावों को समझना $#arrचाहिए , हालांकि वे हैं। $[
कीथ थॉम्पसन

41

पहला, दूसरा अन्य दो के बराबर नहीं है। $#arrayसरणी के अंतिम सूचकांक को लौटाता है, जो कि सरणी के आकार से एक कम है।

अन्य दो वस्तुतः एक ही हैं। आप केवल स्केलर संदर्भ बनाने के लिए दो अलग-अलग साधनों का उपयोग कर रहे हैं। यह पठनीयता के सवाल पर आता है।

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

say 0+@array;          # Represent @array as a number

मुझे यह स्पष्ट है

say scalar(@array);    # Represent @array as a scalar

तथा

my $size = @array;
say $size;

उत्तरार्द्ध इस तरह अकेले काफी स्पष्ट दिखता है, लेकिन मुझे लगता है कि अतिरिक्त कोड स्पष्टता से दूर ले जाता है जब अन्य कोड का हिस्सा होता है। यह सिखाने के लिए उपयोगी है कि @arrayस्केलर के संदर्भ में क्या होता है, और यदि आप $sizeएक से अधिक बार उपयोग करना चाहते हैं ।


15
व्यक्तिगत रूप से मैं "स्केलर" कीवर्ड का उपयोग करने वाले संस्करण को पसंद करता हूं, क्योंकि यह काफी स्पष्ट है कि यह एक स्केलर संदर्भ को मजबूर कर रहा है। my $size=@arrayऐसा लग रहा है कि यह एक गलती हो सकती है जहां गलत सर्जन का इस्तेमाल किया गया था।
नैट सीके

5
यह एक बहुत बुरा विचार है। जो लोग scalarबिना किसी कारण के उपयोग करते हैं, वे गलत सबक सीखते हैं। वे अपने सिर में होने लगते हैं कि ऑपरेटर उन सूचियों को लौटाते हैं जिन्हें स्केलर में ज़ब्त किया जा सकता है। दर्जनों बार देखा।
ikegami

2
यह "कोई कारण नहीं" क्यों है? आप उपयोग scalarकर रहे हैं क्योंकि आप सूची को एक अदिश संदर्भ में ले जा रहे हैं। यही इसका उपयोग करने का सही कारण है। आपका उदाहरण बिल्कुल वही काम करता है, लेकिन जब आप किसी अनुमानित स्केलर संदर्भ में सूची चर का मूल्यांकन करते हैं तो पर्ल क्या करता है, इस पर निर्भर करता है। इस प्रकार, आपके उदाहरण के लिए पाठक को उस संदर्भ में पर्ल के निहित व्यवहार के बारे में जानना होगा। आप अभिव्यक्ति में निहित व्यवहार की एक और परत जोड़ रहे हैं, और पर्ल में पहले से ही बहुत अधिक अंतर्निहित व्यवहार है जिसे आपको एक कार्यक्रम को समझने के लिए तर्क करना होगा।
नैट सीके

2
@Nate CK, Re "यह" कोई कारण नहीं है "? आप का उपयोग scalarकर रहे हैं क्योंकि आप सूची को एक स्केलर संदर्भ में ले जा रहे हैं", आपने गलत पाठ सीखने के बारे में मेरी बात साबित कर दी है। यह पूरी तरह से झूठ है। कोई सूची कभी भी ज़ब्त नहीं की जाती है scalar। (अगर यह किया है, scalar(@array)और scalar(@array[0..$#array])एक ही बात वापस आ जाएगी।) एक स्केलर वापस करने के लिए scalar(@array)कहता @arrayहै, जिसे आपने पहले से ही बताया था my $size=
ikegami

2
मानो या न मानो, डेवलपर्स को अन्य डेवलपर्स द्वारा लिखे गए कोड को डीबग करना होगा। और डेवलपर्स को कोड को डीबग करना होगा जो उन्होंने तीन साल पहले लिखा था।
नैट सीके

27

यह सरणी को स्केलर संदर्भ में मजबूर करके आकार प्राप्त करता है, जिसमें इसका आकार के रूप में मूल्यांकन किया जाता है:

print scalar @arr;

यह एक स्केलर संदर्भ में सरणी को मजबूर करने का एक और तरीका है, क्योंकि इसे स्केलर चर में सौंपा जा रहा है:

my $arrSize = @arr;

यह सरणी में अंतिम तत्व का सूचकांक प्राप्त करता है, इसलिए यह वास्तव में आकार 1 माइनस है (मानकर अनुक्रमित 0 से शुरू होता है, जो पर्ल में समायोज्य है, हालांकि ऐसा करना आमतौर पर एक बुरा विचार है):

print $#arr;

यह पिछले एक सरणी आकार प्राप्त करने के लिए उपयोग करने के लिए वास्तव में अच्छा नहीं है। यदि आप सरणी का अंतिम तत्व प्राप्त करना चाहते हैं तो यह उपयोगी होगा:

my $lastElement = $arr[$#arr];

इसके अलावा, जैसा कि आप यहां स्टैक ओवरफ्लो पर देख सकते हैं, यह निर्माण अधिकांश सिंटैक्स हाइलाइटर्स द्वारा सही ढंग से नहीं संभाला गया है ...


2
एक सिडनोट: बस $arr[-1]अंतिम तत्व प्राप्त करने के लिए उपयोग करें। और $arr[-2]तपस्या प्राप्त करने के लिए, और इसी तरह।
tuomassalo

1
@tuomassalo: मैं मानता हूं कि आपका सुझाव एक बेहतर तरीका है। पूर्वव्यापी में, $#arrएक बहुत ही उपयोगी विशेषता नहीं है, और यह कोई दुर्घटना नहीं है कि अन्य भाषाओं में यह नहीं है।
नैट सीके

6

दूसरे तरीके का उपयोग करने के लिए, 1 जोड़ें:

print $#arr + 1; # Second way to print array size

for [0..$#array] { print $array[$_ ] } वास्तव में अच्छी तरह से काम करता है, हालांकि तत्वों की संख्या प्राप्त करने का उद्देश्य सरणी के माध्यम से पुनरावृति करना है। फायदा यह है कि आपको एलीमेंट के साथ-साथ एलीमेंट भी मिलते हैं।
15

5

यदि हम दूसरे को थोड़ा संशोधित करते हैं तो तीनों ही परिणाम देते हैं:

my @arr = (2, 4, 8, 10);

print "First result:\n";
print scalar @arr; 

print "\n\nSecond result:\n";
print $#arr + 1; # Shift numeration with +1 as it shows last index that starts with 0.

print "\n\nThird result:\n";
my $arrSize = @arr;
print $arrSize;

5
क्या यह पहले से ही इस उत्तर और इस एक में वर्णित से अलग है ?
देवनुल

5

उदाहरण:

my @a = (undef, undef);
my $size = @a;

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2

2

"पर्ल चर प्रकार" अनुभाग के perlintro प्रलेखन शामिल

विशेष चर $#arrayआपको किसी सरणी के अंतिम तत्व का सूचकांक बताता है:

print $mixed[$#mixed];       # last element, prints 1.23

आपको यह $#array + 1बताने के लिए उपयोग करने के लिए लुभाया जा सकता है कि एक सरणी में कितने आइटम हैं। परेशान मत करो। जैसा कि होता है, @arrayजहां पर्ल एक स्केलर मान ("स्केलर संदर्भ में") खोजने की अपेक्षा करता है, आपको एरे में तत्वों की संख्या देगा:

if (@animals < 5) { ... }

Perldata प्रलेखन भी इस को शामिल किया गया "अदिश मूल्यों" खंड

यदि आप स्केलर संदर्भ में किसी सरणी का मूल्यांकन करते हैं, तो यह सरणी की लंबाई लौटाता है। (ध्यान दें कि यह सूचियों का सच नहीं है, जो अंतिम मान लौटाते हैं, जैसे सी कॉमा ऑपरेटर, न ही अंतर्निहित कार्य, जो वापस लौटने पर जैसा भी महसूस करते हैं।) हमेशा निम्न सत्य होता है:

scalar(@whatever) == $#whatever + 1;

कुछ प्रोग्रामर एक स्पष्ट रूपांतरण का उपयोग करना चाहते हैं ताकि संदेह के बिना कुछ न छोड़ें:

$element_count = scalar(@whatever);

इससे पहले एक ही खंड दस्तावेजों में एक सरणी के अंतिम तत्व के सूचकांक को कैसे प्राप्त किया जाए।

एक सरणी की लंबाई एक स्केलर मान है। आप के रूप में @daysमूल्यांकन करके सरणी की लंबाई पा सकते हैं । हालाँकि, यह सरणी की लंबाई नहीं है; यह अंतिम तत्व का सबस्क्रिप्ट है, जो कि 0 वें तत्व के बाद से एक अलग मूल्य है।$#dayscsh


2

सरणी के आकार को प्रिंट करने के विभिन्न तरीके हैं। यहाँ सभी के अर्थ हैं: कहते हैं कि हमारी सरणी हैmy @arr = (3,4);

विधि 1: अदिश

यह सरणियों का आकार प्राप्त करने का सही तरीका है।

print scalar @arr;  # prints size, here 2

विधि 2: सूचकांक संख्या

$#arrकिसी सरणी का अंतिम सूचकांक देता है। इसलिए यदि सरणी 10 आकार की है तो इसका अंतिम सूचकांक 9 होगा।

print $#arr;     # prints 1, as last index is 1
print $#arr + 1; # Add 1 to last index to get array size

हम यहां 1 को जोड़ रहे हैं, जिसमें 0-अनुक्रमित के रूप में सरणी पर विचार किया गया है । लेकिन, अगर इसका शून्य आधारित नहीं है, तो यह तर्क विफल हो जाएगा

perl -le 'local $[ = 4; my @arr=(3,4); print $#arr + 1;'   # prints 6

उपरोक्त उदाहरण 6 को प्रिंट करता है, क्योंकि हमने इसके प्रारंभिक सूचकांक को 4. पर सेट किया है। अब सूचकांक क्रमशः 3 और 4 के साथ 5 और 6 होगा।

विधि 3:

जब स्केलर संदर्भ में एक सरणी का उपयोग किया जाता है, तो यह सरणी का आकार लौटाता है

my $size = @arr;
print $size;   # prints size, here 2

वास्तव में विधि 3 और विधि 1 समान हैं।


2

Perldoc से perldata , जो बोली के लिए सुरक्षित किया जाना चाहिए:

निम्नलिखित हमेशा सच होता है:

scalar(@whatever) == $#whatever + 1;

बस जब तक आप $ # जो भी ++ नहीं करते हैं और रहस्यमय तरीके से आकार या आपके सरणी को बढ़ाते हैं।

सरणी सूचकांकों की शुरुआत 0 से होती है।

तथा

आप अशक्त सूची () को असाइन करके कुछ भी नहीं करने के लिए नीचे एक सरणी काट सकते हैं। निम्नलिखित समतुल्य हैं:

    @whatever = ();
    $#whatever = -1;

जो मुझे उस चीज़ के लिए लाता है जिसे मैं देख रहा था कि कैसे सरणी का पता लगाना है। मैंने इसे $ # खाली == -1 पाया;


1

क्या के बारे में के int(@array)रूप में यह अदिश के रूप में तर्क की धमकी दी।


0

किसी सरणी का आकार खोजने के लिए scalarकीवर्ड का उपयोग करें :

print scalar @array;

किसी सरणी के अंतिम सूचकांक का पता लगाने के लिए $#(पर्ल डिफ़ॉल्ट चर) है। यह एक सरणी का अंतिम सूचकांक देता है। जैसे ही कोई सरणी 0 से शुरू होती है, हम एक से जोड़कर सरणी का आकार प्राप्त करते हैं $#:

print "$#array+1";

उदाहरण:

my @a = qw(1 3 5);
print scalar @a, "\n";
print $#a+1, "\n";

आउटपुट:

3

3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.