J'ai le code suivant:
$project.PropertyGroup | Foreach {
if($_.GetAttribute('Condition').Trim() -eq $propertyGroupConditionName.Trim()) {
$a = $project.RemoveChild($_);
Write-Host $_.GetAttribute('Condition')"has been removed.";
}
};
Question n ° 1: Comment puis-je quitter ForEach? J'ai essayé d'utiliser "break" et "continue", mais cela ne fonctionne pas.
Question n ° 2: j'ai constaté que je pouvais modifier la liste dans une boucle foreach
... Nous ne pouvons pas le faire comme cela en C # ... Pourquoi PowerShell nous permet-il de le faire?
Objet 1. Placer un break
dans la boucle foreach
quitte la boucle, mais n'arrête pas le pipeline. On dirait que vous voulez quelque chose comme ça:
$todo=$project.PropertyGroup
foreach ($thing in $todo){
if ($thing -eq 'some_condition'){
break
}
}
Point n ° 2 PowerShell vous permet de modifier un tableau dans une boucle foreach
par-dessus ce tableau, mais ces modifications ne prendront effet que lorsque vous aurez quitté la boucle. Essayez d’exécuter le code ci-dessous pour un exemple.
$a=1,2,3
foreach ($value in $a){
Write-Host $value
}
Write-Host $a
Je ne peux pas dire pourquoi les auteurs de PowerShell ont autorisé cela, mais la plupart des autres langages de script ( Perl , Python et Shell) autorisent des constructions similaires.
Pour arrêter le pipeline dont ForEach-Object
Fait partie, utilisez simplement l'instruction continue
à l'intérieur du bloc de script sous ForEach-Object
. continue
se comporte différemment lorsque vous l'utilisez dans foreach(...) {...}
et dans ForEach-Object {...}
, raison pour laquelle c'est possible. Si vous souhaitez continuer à produire des objets dans le pipeline en supprimant certains des objets d'origine, la meilleure façon de le faire est de filtrer à l'aide de Where-Object
.
Il y a des différences entre foreach
et foreach-object
.
Une très bonne description que vous pouvez trouver ici: MS-ScriptingGuy
Pour tester en PS, vous avez ici des scripts pour montrer la différence.
Pour chaque objet:
# Omit 5.
1..10 | ForEach-Object {
if ($_ -eq 5) {return}
# if ($_ -ge 5) {return} # Omit from 5.
Write-Host $_
}
write-Host "after1"
# Cancels whole script at 15, "after2" not printed.
11..20 | ForEach-Object {
if ($_ -eq 15) {continue}
Write-Host $_
}
write-Host "after2"
# Cancels whole script at 25, "after3" not printed.
21..30 | ForEach-Object {
if ($_ -eq 25) {break}
Write-Host $_
}
write-Host "after3"
pour chaque
# Ends foreach at 5.
foreach ($number1 in (1..10)) {
if ($number1 -eq 5) {break}
Write-Host "$number1"
}
write-Host "after1"
# Omit 15.
foreach ($number2 in (11..20)) {
if ($number2 -eq 15) {continue}
Write-Host "$number2"
}
write-Host "after2"
# Cancels whole script at 25, "after3" not printed.
foreach ($number3 in (21..30)) {
if ($number3 -eq 25) {return}
Write-Host "$number3"
}
write-Host "after3"
Il n’existe AUCUN moyen simple de sortir d’un pipeline, mais vous pouvez appliquer des filtres à l’aide de Where-Object
. Dans la mesure du possible, la meilleure solution consiste à convertir Foreach-Object
(où les objets sont passés par pipe) dans une construction de boucle standard Foreach
, par exemple:
Foreach-Object
(objets passant dans le pipeline):
1..10 | Foreach-Object {
if ($_ -eq 3) {return;}
£_;
}
Write-Host "Only skips one iteration (iterates all 10 times)";
Converti en construction de boucle Foreach
standard:
Foreach ($i in 1..10) {
if ($i -eq 3) {break;}
$i;
}
Write-Host "Ends the loop after 2nd iteration (iterates only 2 times)";
Idem avec Where-Object
filtre (où la conversion en boucle Foreach
n'est pas possible):
1..10 | Where-Object {$_ -le 2} | Foreach-Object {
$_;
}
Write-Host "Ends the loop after 2nd iteration (iterates only 2 times)";
HTH