Если я сделаю следующее в сценарии PowerShell:
$range = 1..100
ForEach ($_ in $range) {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
Я получаю ожидаемый результат:
7 is a multiple of 7
14 is a multiple of 7
21 is a multiple of 7
28 is a multiple of 7
35 is a multiple of 7
42 is a multiple of 7
49 is a multiple of 7
56 is a multiple of 7
63 is a multiple of 7
70 is a multiple of 7
77 is a multiple of 7
84 is a multiple of 7
91 is a multiple of 7
98 is a multiple of 7
Однако, если я использую конвейер и ForEach-Object
, continue
кажется, вырвется из цикла конвейера.
1..100 | ForEach-Object {
if ($_ % 7 -ne 0 ) { continue; }
Write-Host "$($_) is a multiple of 7"
}
Могу ли я добиться continue
подобного поведения при выполнении ForEach-Object, чтобы мне не пришлось разбивать конвейер?
powershell
foreach
Джастин Диринг
источник
источник
foreach
: techotopia.com/index.php/…Ответы:
Просто используйте
return
вместоcontinue
. Этоreturn
возвращается из блока сценария, который вызываетсяForEach-Object
на определенной итерации, таким образом, он имитируетcontinue
цикл.При рефакторинге следует иметь в виду одну хитрость. Иногда кто-то хочет преобразовать
foreach
блок операторов в конвейер с помощьюForEach-Object
командлета (у него даже есть псевдоним,foreach
который помогает упростить это преобразование и также легко исправить ошибки). Всеcontinue
s следует заменить наreturn
.PS: К сожалению, это не так легко имитировать
break
вForEach-Object
.источник
continue
можно использовать для имитацииbreak
inForEach-Object
:)continue
сломает весь сценарий, а не только то,ForEach-Object
где он используется.Поскольку
For-Each
объект является командлет , а не цикл , аcontinue
иbreak
не применять к нему.Например, если у вас есть:
Вы получите следующий результат:
Это связано с тем, что
continue
применяется к внешнему циклу foreach, а не к командлету foreach-object. В отсутствие петли это самый внешний уровень, поэтому создается впечатление, что он действует какbreak
.Так как же добиться
continue
подобного поведения? Один из способов, конечно, это Where-Object :источник
In my actual case, I don't think it makes sense to make the multiple lines of code preceding my if statement into a single long line of hard to read code.
Что ты имеешь в виду?Другой вариант - это своего рода взлом, но вы можете заключить свой блок в цикл, который будет выполняться один раз. Таким образом,
continue
будет желаемый эффект:источник
Простое
else
утверждение заставляет его работать так:Или в одном конвейере:
Но более элегантное решение - перевернуть тест и генерировать результат только для ваших успехов.
источник