6

I have the following loop structure:

while ($reader.Read() -eq $true)
{
    $row = @{}
    for ($i = 0; $i -lt $reader.FieldCount; $i++)
    {
        if(something...)
        {
            #continue with while
        }
    }
    #do more stuff...          
}

Now, is there any way to continue from within the for loop with the next iteration of the outer while loop without any break-variable? So if "something is true" I do not want to go #do more stuff but instead do the next $reader.read(). Continue only goes to the next iteration of the for loop. Break will only break the for loop.

2 Answers 2

13

Factoring out the inner loop to a function could improve readability, depending on how tangled up your variables are.

function processRow($reader) {
    $row = @{}
    for ($i = 0; $i -lt $reader.FieldCount; $i++)
    {
        if(-not something...) { return $null }
        # process row
    }
    $row
}

while ($reader.Read()) {
    $row = processRow $reader
    if ($row) {
        #do more stuff...          
    }
}

But if you want to do this directly, you can, because PowerShell has labeled breaks:

:nextRow while ($reader.Read()) {
    $row = @{}
    for ($i = 0; $i -lt $reader.FieldCount; $i++) {
        if(something...) {
            #continue with while
            continue nextRow
        }
    }
    #do more stuff...          
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, those labled breaks seem to do the trick - though it feels somewhat like good old GOTO :)
Labeled breaks are what Donald Knuth would call a "structured GOTO" -- you cannot transfer execution to arbitrary places, only to well-defined ones (namely the ends of loops). To reinforce that, PowerShell doesn't even have a GOTO statement, which is fairly rare for a scripting language.
Just a small edit: It's continue nextRow not break :nextRow
You're absolutely right -- break :nextRow will terminate the outer loop from inside the for, which is not what we want (in this case, but it's also useful).
for me continue nextRow only works without the : With the : it will continue the for-loop
|
0

EDIT: a revised, recursive (and untested!) solution so your millage may vary:

function doReader()
{
    while ($reader.Read() -eq $true)
    {
        $row = @{}
        for ($i = 0; $i -lt $reader.FieldCount; $i++)
        {
            if(something...)
            {
                #continue with while
                doReader
                break;
            }
        }
    }
}
doReader
#do more stuff

3 Comments

Yeah, that's what I meant with "extra break-variable". I am currently using this but was looking for a nicer way ;)
@silent, give the edited answer a shot. Recursion is certainly more elegant
I wouldn't use recursion in a scripting language, because I wouldn't expect my future maintainer to understand it -- and I say this with all fondness for my future maintainers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.