2012-04-23 10 views
41

Tengo el siguiente código:Cómo salir de ParaCada a objetos con PowerShell

$project.PropertyGroup | Foreach { 
    if($_.GetAttribute('Condition').Trim() -eq $propertyGroupConditionName.Trim()) { 
     $a = $project.RemoveChild($_); 
     Write-Host $_.GetAttribute('Condition')"has been removed."; 
    } 
}; 

Pregunta # 1: ¿Cómo se sale de ParaCada? Intenté usar "break" y "continue", pero no funciona.

Pregunta # 2: Encontré que puedo alterar la lista dentro de un bucle foreach ... No podemos hacerlo así en C# ... ¿Por qué PowerShell nos permite hacer eso?

Respuesta

69

Artículo n. ° 1. Poner un break dentro del bucle foreach sale del bucle, pero no detiene la tubería. Parece que quiere algo como esto:

$todo=$project.PropertyGroup 
foreach ($thing in $todo){ 
    if ($thing -eq 'some_condition'){ 
     break 
    } 
} 

Artículo n. ° 2. PowerShell le permite modificar una matriz dentro de un bucle foreach sobre esa matriz, pero esos cambios no tendrán efecto hasta que salga del bucle. Intenta ejecutar el siguiente código para ver un ejemplo.

$a=1,2,3 
foreach ($value in $a){ 
    Write-Host $value 
} 
Write-Host $a 

que no puedo comentar sobre por qué los autores de PowerShell permite esto, pero la mayoría de los otros lenguajes de scripting (Perl, Python y concha) permiten construcciones similares.

+0

Creo que quisiste agregar una línea como '$ a = 1..23;' en tu ciclo para mostrar que los cambios no se reflejan en la ejecución del ciclo medio. – ruffin

+1

El elemento n.º 2 es incorrecto (al menos con v5 con una matriz de tamaño fijo). Puede modificar la matriz y hacerla visible dentro de la construcción 'ForEach'. Si tuviera que agregar '$ a [1] = 9' dentro del constructo' ForEach', se mostrará 9 como el 2º elemento, pero no puede agregar/eliminar elementos de la matriz y cualquier cosa que agregue usando el '+ = 'el operador no se mostrará hasta el final. Si no es una matriz de tamaño fijo (es decir, '$ a = [System.Collections.ArrayList] @ (1,2,3)'), cualquier intento de modificar el contenido provocará que 'Collection se haya modificado; la operación de enumeración no puede ejecutar el error., terminando el ciclo. – Adrian

+1

Esta es una respuesta completamente incorrecta. La pregunta es con respecto a 'Foreach-Object'. En powershell (muy molesto gotcha btw) 'foreach' es un" operador "y un" alias ". 'foreach' provisto en esta respuesta por smeltplate es el" operador "y no el" alias ". Ver [aquí.] (Https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/08/getting-to-know-foreach-and-foreach-object/) Nota: esta respuesta es una refactorización completa de código y puede no funcionar en muchas situaciones. –

6

Para detener la tubería de la cual ForEach-Object es parte simplemente use la instrucción continue dentro del bloque de script bajo ForEach-Object. continue se comporta de manera diferente cuando lo usa en foreach(...) {...} y en ForEach-Object {...} y es por eso que es posible. Si desea continuar produciendo objetos en la tubería descartando algunos de los objetos originales, entonces la mejor manera de hacerlo es filtrando usando Where-Object.

+0

+1. Interesante. Nunca supe esto. Parece que funciona igual si usas 'break' o' continue'. Me pregunto por qué esto no funcionó para el autor de la pregunta, ya que dijeron que probaron ambos. – BACON

+0

¿Alguna idea de dónde está documentado esto? ['about_break'] (https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_break) y [' about_continue'] (https://docs.microsoft.com/powershell/module /microsoft.powershell.core/about/about_continue) solo hablan de las instrucciones 'for',' foreach', 'while' y' switch'. ['ForEach-Object'] (https://docs.microsoft.com/powershell/module/microsoft.powershell.core/foreach-object) no hace mención de' break' o 'continue'. – BACON

+0

Esto no funciona para mí - Obtengo una excepción de Continuar en 'Get-ADGroupMember' – PeterX

-1

Para "continuar" dentro de una tubería ForEach-Object simplemente use return. Hace lo que esperaría que hiciera continue: omite el resto del bloque y continúa con la siguiente iteración.

+0

Necesito salir del ciclo - Recibo excepciones con break y continue ... y return solo sigue procesando para' Get-ADGroupMember' – PeterX