I have a condition embedded in a Loop, Try, Switch and if the condition is met, I want to gracefully exit the Loop iteration and go onto the next Loop value. I’m trying to use the Break however that command is exiting the Switch command not the loop iteration. Please assist.
In the following sample of my actual code, Whenever the Orange or Green conditions are met, exit the loop and check the next color- do not execute the rest of the Loop code:
$colors = @(“Red”,”Orange”,”Yellow”,”Green”,”Blue”,”Indigo”,”Violet”)
:ExitLoop For ($i=0; $i -lt $colors.Length; $i++)
{
Try
{
Switch ($colors[$i])
{
"Orange"
{
Write-Host "[$i] Orange"
Write-Host "[$i] Stop code execution"
Break
}
"Green"
{
Write-Host "[$i] Green"
Write-Host "[$i] Stop code execution"
Break ExitLoop
}
}
# Bypass this line of code if the color is Orange or Green.
Write-Host "[$i] Continuation of code without interruption"
}
Catch
{
Write-Host "Error"
}
}
$colors = @(“Red”,”Orange”,”Yellow”,”Green”,”Blue”,”Indigo”,”Violet”)
:ExitLoop For ($i=0; $i -lt $colors.Length; $i++)
{
Try
{
Write-Host "Processing [$i] $($Colors[$i])"
Switch ($colors[$i])
{
"Orange"
{
Write-Host "[$i] Orange found"
Write-Host "[$i] Stop code execution and goto next color"
Write-Host "+------------------------------------------+"
Break
}
"Green"
{
Write-Host "[$i] Green found"
Write-Host "[$i] Stop code execution and goto next color"
Write-Host "+------------------------------------------+"
Break
}
}
# Bypass this line of code if the color is Orange or Green.
Write-Host "[$i] [$($Colors[$i])] Continuation of code without interruption"
Write-Host "Processing additional steps for color [$($Colors[$i])]"
Write-Host "+===========================================+"
}
Catch
{
Write-Host "Error"
}
}
This code does not work as required as shown by this output. The Break command only exits the Switch block:
Processing [0] Red
[0] [Red] Continuation of code without interruption
Processing additional steps for color [Red]
+===========================================+
Processing [1] Orange
[1] Orange found
[1] Stop code execution and goto next color
+------------------------------------------+
[1] [Orange] Continuation of code without interruption
Processing additional steps for color [Orange]
+===========================================+
Processing [2] Yellow
[2] [Yellow] Continuation of code without interruption
Processing additional steps for color [Yellow]
+===========================================+
Processing [3] Green
[3] Green found
[3] Stop code execution and goto next color
+------------------------------------------+
[3] [Green] Continuation of code without interruption
Processing additional steps for color [Green]
+===========================================+
Processing [4] Blue
[4] [Blue] Continuation of code without interruption
Processing additional steps for color [Blue]
+===========================================+
Processing [5] Indigo
[5] [Indigo] Continuation of code without interruption
Processing additional steps for color [Indigo]
+===========================================+
Processing [6] Violet
[6] [Violet] Continuation of code without interruption
Processing additional steps for color [Violet]
+===========================================+
Changing the Break to Continue, results in this output. Seems changing to Continue makes no difference:
Processing [0] Red
[0] [Red] Continuation of code without interruption
Processing additional steps for color [Red]
+===========================================+
Processing [1] Orange
[1] Orange found
[1] Stop code execution and goto next color
+------------------------------------------+
[1] [Orange] Continuation of code without interruption
Processing additional steps for color [Orange]
+===========================================+
Processing [2] Yellow
[2] [Yellow] Continuation of code without interruption
Processing additional steps for color [Yellow]
+===========================================+
Processing [3] Green
[3] Green found
[3] Stop code execution and goto next color
+------------------------------------------+
[3] [Green] Continuation of code without interruption
Processing additional steps for color [Green]
+===========================================+
Processing [4] Blue
[4] [Blue] Continuation of code without interruption
Processing additional steps for color [Blue]
+===========================================+
Processing [5] Indigo
[5] [Indigo] Continuation of code without interruption
Processing additional steps for color [Indigo]
+===========================================+
Processing [6] Violet
[6] [Violet] Continuation of code without interruption
Processing additional steps for color [Violet]
+===========================================+
Adding the label after each Continue seems to do what I want it to do:
Processing [0] Red
[0] [Red] Continuation of code without interruption
Processing additional steps for color [Red]
+===========================================+
Processing [1] Orange
[1] Orange found
[1] Stop code execution and goto next color
+------------------------------------------+
Processing [2] Yellow
[2] [Yellow] Continuation of code without interruption
Processing additional steps for color [Yellow]
+===========================================+
Processing [3] Green
[3] Green found
[3] Stop code execution and goto next color
+------------------------------------------+
Processing [4] Blue
[4] [Blue] Continuation of code without interruption
Processing additional steps for color [Blue]
+===========================================+
Processing [5] Indigo
[5] [Indigo] Continuation of code without interruption
Processing additional steps for color [Indigo]
+===========================================+
Processing [6] Violet
[6] [Violet] Continuation of code without interruption
Processing additional steps for color [Violet]
+===========================================+
So, when you need to exit a nested code block, labels need to be used and referenced by the Continue statements.
You would need the label when it’s nested because break in a switch block exits the switch construct and so continues processing the code in your for loop.
break with a label would cause your for loop to stop.
continue without a label also exits the switch construct because in your code, you’re only passing one element (the current item in the for loop) to the switch statement. Again, this causes the rest of the code in your for loop to execute.
You don’t need to use a for loop to process each item, the switch construct will iterate over an array of items. Knowing this, you can avoid the nested loop. As you’re performing the same actions for the groups of colours you can also simplify the conditions:
$colors = @('Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet')
function Invoke-ProcessColor {
param(
$Color
)
Write-Host "Processing additional steps for $color"
}
switch ($colors) {
{ $_ -in @('Orange', 'Green') } {
Write-Host "$_ found, stop code execution and go to next colour."
}
default {
Invoke-ProcessColor -Color $_
}
}