Sök…
Introduktion
En slinga är en sekvens av instruktioner som upprepas kontinuerligt tills ett visst tillstånd har uppnåtts. Att kunna göra att ditt program upprepade gånger kör ett kodblock är en av de mest grundläggande men användbara uppgifterna i programmeringen. En slinga låter dig skriva ett mycket enkelt uttalande för att ge ett betydligt större resultat helt enkelt genom upprepning. Om villkoret har uppnåtts, faller nästa instruktion "igenom" till nästa sekvensinstruktion eller grenar utanför slingan.
Syntax
för (<Initiering>; <Villkor>; <Upprepning>) {<Script_Block>}
<Samling> | Foreach-Object {<Script_Block_med _ $ __ as_current_item>}
förhand (<Item> i <Utsamling>) {<Script_Block>}
medan (<Kondition>) {<Script_Block>}
gör {<Script_Block>} medan (<Kondition>)
gör {<Script_Block>} tills (<Villkor>)
<Collection> .foreach ({<Script_Block_med _ $ __ as_current_item>})
Anmärkningar
För varje
Det finns flera sätt att driva en foreach-loop i PowerShell och alla ger sina egna fördelar och nackdelar:
Lösning | fördelar | nackdelar |
---|---|---|
Foreach-uttalande | Snabbast. Fungerar bäst med statiska samlingar (lagras i en variabel). | Ingen pipeline-ingång eller -utgång |
ForEach () -metod | Samma skriptblocksyntax som Foreach-Object , men snabbare. Fungerar bäst med statiska samlingar (lagras i en variabel). Stöder pipeline output. | Inget stöd för pipeline-ingång. Kräver PowerShell 4.0 eller högre |
Foreach-objekt (cmdlet) | Stöder pipeline-ingång och -utgång. Stöder start- och slutskriptblock för initialisering och stängning av anslutningar etc. Mest flexibel lösning. | Långsammast |
Prestanda
$foreach = Measure-Command { foreach ($i in (1..1000000)) { $i * $i } }
$foreachmethod = Measure-Command { (1..1000000).ForEach{ $_ * $_ } }
$foreachobject = Measure-Command { (1..1000000) | ForEach-Object { $_ * $_ } }
"Foreach: $($foreach.TotalSeconds)"
"Foreach method: $($foreachmethod.TotalSeconds)"
"ForEach-Object: $($foreachobject.TotalSeconds)"
Example output:
Foreach: 1.9039875
Foreach method: 4.7559563
ForEach-Object: 10.7543821
Medan Foreach-Object
är det långsammaste kan stödet från pipeline vara användbart eftersom det låter dig bearbeta objekt när de kommer (medan du läser en fil, tar emot data etc.). Detta kan vara mycket användbart när du arbetar med big data och lågt minne eftersom du inte behöver ladda all data till minnet innan du bearbetar.
För
for($i = 0; $i -le 5; $i++){
"$i"
}
En typisk användning av for-loopen är att arbeta på en delmängd av värdena i en matris. I de flesta fall, om du vill upprepa alla värden i en matris, kan du överväga att använda en förhandssatsning.
För varje
ForEach
har två olika betydelser i PowerShell. Det ena är ett nyckelord och det andra är ett alias för cmdleten ForEach-Object . Den förstnämnda beskrivs här.
Detta exempel visar att du skriver ut alla objekt i en matris till konsolen värd:
$Names = @('Amy', 'Bob', 'Celine', 'David')
ForEach ($Name in $Names)
{
Write-Host "Hi, my name is $Name!"
}
Detta exempel visar fånga utdata från en ForEach-slinga:
$Numbers = ForEach ($Number in 1..20) {
$Number # Alternatively, Write-Output $Number
}
I likhet med det sista exemplet, demonstrerar detta exempel istället att skapa en matris innan slingan lagras:
$Numbers = @()
ForEach ($Number in 1..20)
{
$Numbers += $Number
}
Medan
En stundslinga kommer att utvärdera ett tillstånd och om det är sant kommer att utföra en åtgärd. Så länge villkoret utvärderar till sann kommer fortsättningen att utföras.
while(condition){
code_block
}
Följande exempel skapar en slinga som räknar ner från 10 till 0
$i = 10
while($i -ge 0){
$i
$i--
}
Till skillnad från Do
-While-loopen utvärderas villkoret innan åtgärdens första utförande. Åtgärden kommer inte att utföras om det ursprungliga villkoret utvärderas till felaktigt.
Obs: Vid utvärdering av villkoret kommer PowerShell att behandla förekomsten av ett returobjekt som sant. Detta kan användas på flera sätt men nedan är ett exempel för att övervaka för en process. Det här exemplet skapar en anteckningsboksprocess och sover sedan det aktuella skalet så länge den processen körs. När du manuellt stänger anteckningar om anteckningsblock misslyckas tillståndet och slingan bryts.
Start-Process notepad.exe
while(Get-Process notepad -ErrorAction SilentlyContinue){
Start-Sleep -Milliseconds 500
}
Foreach-Object
ForEach-Object
fungerar på samma sätt som foreach
uttalande, men tar dess input från pipeline.
Grundläggande användning
$object | ForEach-Object {
code_block
}
Exempel:
$names = @("Any","Bob","Celine","David")
$names | ForEach-Object {
"Hi, my name is $_!"
}
Foreach-Object
har två standardalias, foreach
och %
(kortfattad syntax). foreach
är %
eftersom foreach
kan förväxlas med förhandens uttalande . Exempel:
$names | % {
"Hi, my name is $_!"
}
$names | foreach {
"Hi, my name is $_!"
}
Avancerad användning
Foreach-Object
sig från de alternativa foreach
lösningarna eftersom det är en cmdlet som betyder att den är utformad för att använda rörledningen. På grund av detta har det stöd för tre skriptblock precis som en cmdlet eller avancerad funktion:
- Börja : körs en gång innan du slingrar igenom artiklarna som kommer från rörledningen. Vanligtvis används för att skapa funktioner för användning i loopen, skapa variabler, öppna anslutningar (databas, webb +) etc.
- Process : körs en gång per artikel anlände från pipeline. "Normal" för varje kodblås. Detta är den standard som används i exemplen ovan när parametern inte är specificerad.
- Slut : körs en gång efter att alla objekt har bearbetats. Vanligtvis används för att stänga anslutningar, generera en rapport etc.
Exempel:
"Any","Bob","Celine","David" | ForEach-Object -Begin {
$results = @()
} -Process {
#Create and store message
$results += "Hi, my name is $_!"
} -End {
#Count messages and output
Write-Host "Total messages: $($results.Count)"
$results
}
Do
Do-loopar är användbara när du alltid vill köra ett kodblock minst en gång. En do-loop kommer att utvärdera tillståndet efter att kodblocket har körts, till skillnad från en while-loop som gör det innan du kör kodblocket.
Du kan använda do-loops på två sätt:
Slinga medan villkoret är sant:
Do { code_block } while (condition)
Slinga tills villkoret är sant, med andra ord, slinga medan villkoret är falskt:
Do { code_block } until (condition)
Verkliga exempel:
$i = 0
Do {
$i++
"Number $i"
} while ($i -ne 3)
Do {
$i++
"Number $i"
} until ($i -eq 3)
Do-While och Do-Till är antonyma slingor. Om koden inuti samma, kommer villkoret att omvändas. Exemplet ovan illustrerar detta beteende.
ForEach () -metod
Istället för ForEach-Object
cmdlet, är här också möjligheten att använda en ForEach
metod direkt på objektmatriser som så
(1..10).ForEach({$_ * $_})
eller - om så önskas - parenteserna runt skriptblocket kan utelämnas
(1..10).ForEach{$_ * $_}
Båda kommer att resultera i utgången nedan
1
4
9
16
25
36
49
64
81
100
Fortsätta
Operatören Continue
fungerar i For
, ForEach
, While
och Do
slingor. Den hoppar över den aktuella iterationen av slingan och hoppar till toppen av den innersta slingan.
$i =0
while ($i -lt 20) {
$i++
if ($i -eq 7) { continue }
Write-Host $I
}
Ovanstående matar ut 1 till 20 till konsolen men missar siffran 7.
Obs : När du använder en rörledningsslinga bör du använda return
istället för Continue
.
Ha sönder
Den break
Operatören kommer att lämna en programslinga omedelbart. Det kan användas i For
, ForEach
, While
och Do
slingor eller i en Switch
uttalande.
$i = 0
while ($i -lt 15) {
$i++
if ($i -eq 7) {break}
Write-Host $i
}
Ovanstående räknas till 15 men stannar så snart 7 har nåtts.
Obs : När du använder en pipeline-slinga, fungerar break
som continue
. För att simulera break
i rörledningsslingan måste du inkludera ytterligare logik, cmdlet, etc. Det är lättare att hålla fast vid öglor utan rörledningar om du behöver använda break
.
Bryt etiketter
Break kan också ringa en etikett som placerades framför inställningen av en slinga:
$i = 0
:mainLoop While ($i -lt 15) {
Write-Host $i -ForegroundColor 'Cyan'
$j = 0
While ($j -lt 15) {
Write-Host $j -ForegroundColor 'Magenta'
$k = $i*$j
Write-Host $k -ForegroundColor 'Green'
if ($k -gt 100) {
break mainLoop
}
$j++
}
$i++
}
Obs: Den här koden kommer att öka $i
till 8
och $j
till 13
vilket gör att $k
lika med 104
. Eftersom $k
överstiger 100
kommer koden då att brytas ut från båda slingorna.