Perl foreach loops
文章推薦指數: 80 %
A foreach loop runs a block of code for each element of a list. No big whoop, “perl foreach” continues to be one of the most popular on ...
MORE:
Togglenavigation
Perl.com
ABOUT
AUTHORS
CATEGORIES
#
TAGS
Perlforeachloops
Sep23,2018by
briandfoy
Aforeachlooprunsablockofcodeforeachelementofalist.Nobigwhoop,“perlforeach”continuestobeoneofthemostpopularonGooglesearchesforthelanguage.Sowethoughtwe’dseewhat’shappenedin20years.IexpandonTomChristiansen’sslidethat’spartofhislongerpresentationthenaddanewbutexperimentalfeatureattheend.Ifyouwantmore,there’splentytoreadinperlsynormybookLearningPerl.
Goingthroughalist
Unlessyousayotherwise,foreachaliasesthecurrentelementtothetopicvariable$_.Youcanspecifythatlistdirectlyintheparenthesesafterforeach,useanarrayvariable,orusetheresultofasubroutinecall(amongstotherwaystogetalist):
foreach(1,3,7){
print"\$_is$_";
}my@numbers=(1,3,7);
foreach(@numbers){
print"\$_is$_";
}subnumbers{return(1,3,7)}
foreach(numbers()){
print"\$_is$_";
}subnumbers{keys%some_hash}
foreach(numbers()){
print"\$_is$_";
}
Somepeopleliketousethesynonymfor.There’saproperC-styleforthathasthreesemicolon-separatedpartsintheparentheses.IfPerldoesn’tseethetwosemicolonsittreatsforjustlikeaforeach:
for(my$i=0;$i<5;$i++){#Cstyle
print"\$iis$i";
}
for(0..4){#foreachsynonym
print"\$_is$_";
}
Elementsourcegotchas
Thealiasingisonlytemporary.Aftertheforeachthetopicvariablereturnstoitsoriginalvalue:
$_="Originalvalue";
my@numbers=(1,3,7);
print"\$_before:$_\n";
foreach(@numbers){
print"\$_is$_\n";
$_=$_*2;
}
print"\$_after:$_\n";
Theoutputshowsthat$_appearsunaffectedbytheforeach:
$_before:Originalvalue
$_is1
$_is3
$_is7
$_after:Originalvalue
Thisisanaliasinsteadofacopy,whichisashortcutthatallowsyourprogramtobealittlefasterbynotmovingdataaround.Ifyouchangethetopicyouchangetheoriginalvalueifthelistsourceisanarray(thevaluesareread-onlyotherwiseandyou’llgetanerror):
my@numbers=(1,3,7);
print"Before:@numbers\n";#Before:137
foreach(@numbers){
print"\$_is$_\n";
$_=$_*2;
}
print"After:@numbers\n";#After:2614
Notonlythat,butifyouchangethesourcebyaddingorremovingelementsyoucanscrewuptheforeach.Thisloopsinfinitelyprocessingthesameelementbecauseeachgothroughtheblockmovesthearrayelementsoveroneposition;whentheiteratormovesontothenextpositionitfindsthesameoneitjustsaw:
my@numbers=(1,3,7);
print"\$numberbefore:$number\n";
foreach$number(@numbers){
print"\$numberis$number\n";
unshift@numbers,"Addedlater";
}
Thisoutputwillgoonforever:
$numberis1
$numberis1
$numberis1
$numberis1
Namingyourowntopicvariable
The$_isoftenhandybecauseit’sthedefaultvariableforseveralPerlfunctions,suchaschomporsplit.Youcanuseyourownnamebyspecifyingascalarvariablebetweentheforeachandtheparentheses.Usuallyyoudon’twanttousethatvariableforsomethingotherthantheloopsotheusualstyledeclaresitinlinewiththeforeach:
foreachmy$number(1,3,7){
print"\$numberis$number";
}
SincePerlflattenslistsintoonebiglist,youcanusemorethanonelistsourceintheparentheses:
my@numbers=(1,3,7);
my@more_numbers=(5,8,13);
foreachmy$number(@numbers,@more_numbers){
print"\$numberis$number";
}
Oramixofsourcetypes:
my@numbers=(1,3,7);
my@more_numbers=(5,8,13);
foreachmy$number(@numbers,numbers(),keys%hash){
print"\$numberis$number";
}
Usingyourownnamedtopicvariableactsjustlikewhatyousawwith$_:
my@numbers=(1,3,7);
my$number='Originalvalue';
say"Before:$number";
foreach$number(@numbers){
say"\$numberis$number";
}
say"After:$number";
Theoutputshowsthealiasingeffectandthattheoriginalvalueisrestoredaftertheforeach:
Before:Originalvalue
$numberis1
$numberis3
$numberis7
After:Originalvalue
Controlling
Therearethreekeywordsthatletyoucontroltheoperationoftheforeach(andotherloopingstructures):last,next,andredo.
Thelaststopsthecurrentiteration.It’sasifyouimmediatelygopastthelaststatementintheblockthenbreaksoutoftheloop.Itdoesnotlookatthenextitem.Youoftenusethiswithapostfixconditional:
foreach$number(0..5){
say"Starting$number";
lastif$number>3;
say"\$numberis$number";
say"Ending$number";
}
say'Pasttheloop';
Youstarttheblockforelement3butendtheloopthereandcontinuetheprogramaftertheloop:
Starting0
$numberis0
Ending0
Starting1
$numberis1
Ending1
Starting2
$numberis2
Ending2
Starting3
Pasttheloop
Thenextstopsthecurrentiterationandmovesontothenextone.Thismakesiteasytoskipelementsthatyoudon’twanttoprocess:
foreachmy$number(0..5){
say"Starting$number";
nextif$number%2;
say"\$numberis$number";
say"Ending$number";
}
Theoutputshowsthatyouruntheblockwitheachelementbutonlytheevennumbersmakeitpastthenext:
Starting0
$numberis0
Ending0
Starting1
Starting2
$numberis2
Ending2
Starting3
Starting4
$numberis4
Ending4
Starting5
Theredorestartsthecurrentiterationofablock.Youcanuseitwithaforeachalthoughit’smorecommonlyusedwithloopingstructuresthataren’tmeanttogothroughalistofitems.
Here’sanexamplewhereyouwanttogetthree“good”linesofinput.Youiteratethroughthenumberoflinesthatyouwantandreadstandardinputeachtime.Ifyougetablankline,yourestartthesameloopwith
my$lines_needed=3;
my@lines;
foreachmy$animal(1..$lines_needed){
chomp(my$line=
延伸文章資訊
- 1Perl continue Statement - Tutorialspoint
A continue BLOCK, is always executed just before the conditional is about to be evaluated again. ...
- 2Perl next Statement
The Perl next statement is used inside a loop to start the next iteration and skip all code below...
- 3What are the Perl equivalents of return and continue keywords ...
return is the equivalent of return. next is the equivalent of continue. last is the equivalent of...
- 4Loop controls: next, last, continue, break - Perl Maven
In Perl there are 3 loop control keywords. The two commonly used are next and last and there is a...
- 55.7 迴圈控制
Perl 常見的迴圈有while、for、foreach、until,在每一種迴圈中,可以視情況, ... 至最外圈。 print "$i\n"; } print "我是j : $j\n"; }...