Как разорвать вложенный цикл foreach в powershell - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть два списка одинаковой длины. Мне нужно выполнить итерацию, чтобы первый элемент в списке A соответствовал первому элементу в списке B. Для этого я создал вложенный цикл foreach, который выглядит следующим образом:

$nodes_table = "a","b","c"
$nodes_list = "a","b","c"

     :Outer foreach ($item in $nodes_table) {
        foreach($node in $nodes_list)
        {
            if($node -eq $item)
            {
                Write-Output "$node hostname matches in vTM"
                break :Outer
            }           
        }        
    }

Проблема: На первой итерации это совпадает. Но во второй итерации внутренний цикл не переходит ко второму элементу, он снова сбрасывается.

First iteration: $node = a equals $item = a
Second iteration: $node = a not equals to $item = b.

Как видите, во второй итерации внутренний цикл не повторялся, он сбрасывался обратно в.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Здесь есть две проблемы. Во-первых, если у вас есть метка типа :Outer foreach(..., имя метки просто Outer, поэтому, когда вы ссылаетесь на нее в выражении break, вы указываете break Outer, а не break :Outer (может быть просто опечатка). Во-вторых, вам нужно использовать оператор continue, а не оператор break. Оператор continue возобновляет выполнение на следующей итерации. Обновленный код выглядит так:

$nodes_table = "a","b","c"
$nodes_list = "a","b","c"

:Outer foreach ($item in $nodes_table) {
    foreach($node in $nodes_list)
    {
        if($node -eq $item)
        {
            Write-Output "$node hostname matches in vTM"
            continue Outer
        }           
    }        
}
0 голосов
/ 26 апреля 2018

Я изменил ваш пример кода следующим образом:

$nodes_table = "a","b","c"
$nodes_list = "a","b","c"

:Outer foreach ($item in $nodes_table) 
{
    foreach($node in $nodes_list)
    {
        Write-Output "item = $item, node = $node" # display values being compared
        if($node -eq $item)
        {
            Write-Output "$node hostname matches in vTM"
            break :Outer
        }           
    }
}

Это дает следующий вывод:

item = a, node = a
a hostname matches in vTM
item = b, node = a
item = b, node = b
b hostname matches in vTM
item = c, node = a
item = c, node = b
item = c, node = c
c hostname matches in vTM

Мне кажется, что он ведет себя правильно.

EDIT

Как указано в ответе Брюса Пайетта ниже, в исходном коде есть дефект, который я скопировал в мой пример выше. Оператор break :Outer неверен, поскольку объектом разрыва должно быть либо ничто, либо имя метки. Символ двоеточия (:) не должен быть там. PowerShell игнорирует эту ошибку и ведет себя так, как будто в операторе break нет метки, тем самым нарушая внутренний цикл, а не внешний цикл. Удалив двоеточие, которое делает строку break Outer, вы увидите, что код сразу переходит к концу внешнего цикла for во время первой итерации внешнего цикла и первой итерации внутреннего цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...