2010-06-05 8 views
12

क्या मैं पर्ल में निम्नलिखित की तरह कुछ कर सकता हूं?क्या मैं अगले तत्व को पर्ल फ़ोरैच लूप के भीतर से खींच सकता हूं?

foreach (@tokens) { 
    if (/foo/){ 
     # simple case, I can act on the current token alone 
     # do something 
     next; 
    } 
    if (/bar/) { 
     # now I need the next token, too 
     # I want to read/consume it, advancing the iterator, so that 
     # the next loop iteration will not also see it 
     my $nextToken = ..... 
     # do something 
     next; 
    } 

} 

अद्यतन: मैं पर्ल में इस की जरूरत है, लेकिन जिज्ञासा की खातिर: क्या अन्य भाषाओं के लिए एक साफ वाक्य रचना है?

उत्तर

19

क्या आप for लूप का उपयोग करना चाहिए? मूल कॉपी और shift साथ यह उपभोग ':

use strict; 
use warnings; 

my @original = 'a' .. 'z'; # Original 
my @array = @original;  # Copy 

while (my $token = shift @array) { 

    shift @array if $token =~ /[nr]/; # consumes the next element 
    print $token; 
} 

# prints 'abcdefghijklmnpqrtuvwxyz' ('s' and 'o' are missing) 
+0

अच्छा। मेरे मामले में, मूल को नष्ट करना भी एक समस्या नहीं है, इसलिए मैं प्रतिलिपि के बिना कर सकता हूं। – Thilo

8

foreach लूप के साथ नहीं।

for (my $i = 0; $i <= $#tokens; ++$i) { 
    local $_ = $tokens[$i]; 
    if (/foo/){ 
    next; 
    } 
    if (/bar/) { 
    my $nextToken = $tokens[++$i]; 
    # do something 
    next; 
    } 
} 

तुम भी Array::Iterator की तरह कुछ इस्तेमाल कर सकते हैं: आप एक सी शैली for पाश का उपयोग कर सकते हैं। मैं उस संस्करण को पाठक के लिए एक अभ्यास के रूप में छोड़ दूंगा। :-)

9

भी सरणियों पर काम करके पर्ल 5.12, each is now more flexible के साथ शुरू:

use 5.012; 
use warnings; 

my @tokens = 'a' .. 'z'; 

while (my ($i, $val) = each @tokens) { 
    if ($val =~ m/[aeiou]/) { 
     ($i, $val) = each @tokens; # get next token after a vowel 
     print $val; 
    } 
} 

# => bfjpv 


एक each साथ चेतावनी, इटरेटर याद वैश्विक है और अगर आप लूप से बाहर निकलते हैं तो रीसेट नहीं किया जाता है।

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

while (my ($i, $val) = each @tokens) { 
    print $val; 
    last if $i == 12; 
} 

# => abcdefghijklm 

my ($i, $val) = each @tokens; 
say "Now at => $val ($i)";   # Now at => n (13) 

तो keys या values का उपयोग मैन्युअल इटरेटर रीसेट करने के लिए:

keys @tokens;      # resets iterator 
($i, $val) = each @tokens; 
say "Now at => $val ($i)";   # Now at => a (0) 
+0

वाह! मुझे नहीं पता था - यह आसान होगा। धन्यवाद :) – zdim

0

मैं Zaids जवाब पसंद है, लेकिन यह सफल नहीं होता तो यह सरणी तो में एक नुल तत्व का सामना करना पड़ता ...

while (@array) { 

    my $token = shift @array; 
    shift @array if $token =~ /[nr]/; # consumes the next element 
    print $token; 
} 

यह नहीं होगा @array तक पी खाली है।

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