2009-07-14 16 views
6

मेरे पास पर्ल में हैश के बारे में जानने की कोशिश करने वाली एक साधारण स्क्रिप्ट है।पर्ल की प्रत्येक() दूसरी बार पूरे हैश के माध्यम से फिर से क्यों नहीं चलती?

#!/usr/bin/perl 

my %set = (
    -a => 'aaa', 
    -b => 'bbb', 
    -c => 'ccc', 
    -d => 'ddd', 
    -e => 'eee', 
    -f => 'fff', 
    -g => 'ggg' 
); 

print "Iterate up to ggg...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
    last if ($val eq 'ggg'); 
} 
print "\n"; 

print "Iterate All...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
} 
print "\n"; 

मैं उत्पादन से हैरान हूं: -

Iterate upto ggg... 
-a -> aaa 
-c -> ccc 
-g -> ggg 

Iterate All... 
-f -> fff 
-e -> eee 
-d -> ddd 
-b -> bbb 

मैं समझता हूँ कि कुंजी टुकड़ों में बांटा जाता है, ताकि पहले उत्पादन आंतरिक आदेश के आधार पर 'एन' तत्व हो सकता है। लेकिन मैं बाद में सरणी को लूप करने में सक्षम क्यों नहीं हूं? क्या गलत है ?

धन्यवाद,

उत्तर

18

each हैश के साथ जुड़े यात्रा का ट्रैक रखने के एक सूचक का उपयोग करता है। यह नहीं जानता कि लूप के दौरान दूसरी बार अलग है, और यह उनके बीच एक ही सूचक रखता है।

अधिकांश लोगों को इस (और अन्य) कारणों के लिए each बचने के लिए, बजाय keys के लिए चयन: वैसे भी

for my $key (sort keys %hash){ 
    say "$key => $hash{$key}"; 
} 

:

for my $key (keys %hash){ 
    say "$key => $hash{$key}"; 
} 

यह आपको यात्रा के क्रम पर नियंत्रण के रूप में अच्छी तरह से देता है , यदि आप लूप को जल्दी समाप्त करने जा रहे हैं, तो each से बचें।

Btw, कार्यात्मक प्रोग्रामिंग अधिवक्ताओं छिपा हुआ राज्य का नुकसान का कहना है करने का अवसर ले जाना चाहिए। एक स्टेटलेस ऑपरेशन की तरह दिखता है ("एक मेज में प्रत्येक जोड़ी पर लूप") वास्तव में काफी सतर्क है।

+0

धन्यवाद अपने कोड में कुंजी% सेट का उपयोग कर सकते हैं। बीटीडब्लू, क्या शुरुआत में 'प्रत्येक' को रीसेट करना संभव है? –

+0

"% हैश =% हैश" काम करता प्रतीत होता है। – jrockway

+6

(perlfaq4 शून्य संदर्भ में हैश पर "कुंजी" बुला पता चलता है। यह अनावश्यक नकल न करना चाहें।) – jrockway

10

आप प्रत्येक

perldoc -f each 

पर perldoc पढ़ सकते हैं जब हैश पूरी तरह से पढ़ने के लिए है, एक अशक्त सरणी सूची संदर्भ में दिया जाता है (जो जब सौंपा एक झूठी (0) मूल्य पैदा करता है), और " स्केलर संदर्भ में "undef"। उसके बाद "प्रत्येक" के लिए अगली कॉल फिर से शुरू हो जाएगी। प्रत्येक हैश के लिए एक पाप- ग्राल इटरेटर है, जो प्रोग्राम में सभी "प्रत्येक", "कुंजी" और "मान" फ़ंक्शन कॉल द्वारा साझा किया जाता है; इसे द्वारा हैश से सभी तत्वों को पढ़ने, या "कुंजी हैश" या "मान HASH" का मूल्यांकन करके रीसेट किया जा सकता है।

इसलिए, आप फिर से (यदि आप "पिछले" बयान के कारण) दोहराने में

print "Iterate upto ggg...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
    last if ($val eq 'ggg'); 
} 
print "\n"; 
keys %set; 
print "Iterate All...\n"; 
while (my ($key, $val) = each %set) { 
    print "$key -> $val \n"; 
} 
print "\n"; 
संबंधित मुद्दे