sort powershell foreach

powershell - sort - ¿Por qué continúa comportándose como una ruptura en un Foreach-Object?



powershell foreach-object (3)

Como For-Each object es un cmdlet y no un bucle y continue / break no se aplica a él.

Por ejemplo, si tiene:

$b = 1,2,3 foreach($a in $b){ $a | foreach { if($_ -eq 2) {continue;} else {write-host $_} } write-host "after" }

obtendrás salida como:

1 after 3 after

Es porque el continuar se aplica al bucle foreach externo y no al cmdlet foreach-object. En ausencia de un bucle, el nivel más externo, por lo tanto, le da una impresión de que actúa como un descanso.

Entonces, ¿cómo consigues continuar como un comportamiento? Una forma es donde, por supuesto, el objeto:

1..100 | ?{ $_ % 7 -eq 0} | %{write-host $_ is a mutliple of 7}

Si hago lo siguiente en un script de powershell:

$range = 1..100 ForEach ($_ in $range){ if ($_ % 7 -ne 0 ) { continue; } Write-Host "$($_) is a multiple of 7" }

Obtengo el resultado esperado de:

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

Sin embargo, si uso una canalización y ForEach-Object , continue parece salir del bucle de la tubería.

1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) { continue; } Write-Host "$($_) is a multiple of 7" }

Mi pregunta es, ¿puedo seguir comportándome de la misma manera mientras sigo haciendo ForEach-Object, para no tener que romper mi pipeline?


Otra alternativa es una especie de truco, pero puedes envolver tu bloque en un bucle que se ejecutará una vez, de esa manera continuará tendrá el efecto deseado:

1..100 | ForEach-Object { for($cont=$true;$cont;$cont=$false){ if ($_ % 7 -ne 0 ) { continue; } Write-Host "$($_) is a multiple of 7" } }


Simplemente use la return lugar de continue . Este return regresa del bloque de script invocado por ForEach-Object en una iteración particular, por lo tanto, simula el continue en un bucle.

1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) { return } Write-Host "$($_) is a multiple of 7" }

Esto es algo que debe tenerse en cuenta en la refactorización. A veces uno quiere convertir un bloque de instrucciones foreach en una canalización con un cmdlet ForEach-Object (incluso tiene el alias foreach que ayuda a facilitar esta conversión y también a cometer errores). Todo continue debe ser reemplazado con return .

PD Desafortunadamente, no es tan fácil simular una break en ForEach-Object .