Вложенный ForEach () в PowerShell

У меня возникли проблемы с вложенными циклами ForEach в Powershell. Во-первых, мне нужно перебрать список 1. Для каждого объекта в списке 1 мне нужно перебрать список 2. Когда я нашел похожий объект в списке 2, я хочу перейти к следующему объекту в списке 1.

Я пробовал перерыв, я пробовал продолжить, но это не сработает для меня.

Function checkLists() {
  ForEach ($objectA in $listA) {
    ForEach ($objectB in $listB) {
       if ($objectA -eq $objectB) {
           // Do something 
           // goto next object in list A and find the next equal object
       }
    }
  }
}

a) что именно делает перерыв/продолжение в PowerShell?

b) как exaclty должен я завоевать мое "проблема"?

4 ответов


использовать метку, как описано в get-help about_break:

A Break statement can include a label. If you use the Break keyword with
a label, Windows PowerShell exits the labeled loop instead of exiting the
current loop

вот так,

foreach ($objectA in @("a", "e", "i")) {
    "objectA: $objectA"
    :outer
    foreach ($objectB in @("a", "b", "c", "d", "e")) {
       if ($objectB -eq $objectA) {
           "hit! $objectB"
           break :outer
       } else { "miss! $objectB" }
    }
}

#Output:
objectA: a
hit! a
objectA: e
miss! a
miss! b
miss! c
miss! d
hit! e
objectA: i
miss! a
miss! b
miss! c
miss! d
miss! e

вот пример использования break / continue. Отмените тест во внутреннем цикле и продолжайте использовать цикл до тех пор, пока тест не завершится неудачно. Как только он получит удар, он разорвет внутренний цикл и вернется к следующему объекту во внешнем цикле.

foreach ($objectA in @("a", "e", "i"))
   {
    "objectA: $objectA"
    foreach ($objectB in @("a", "b", "c", "d", "e")) {
       if ($objectB -ne $objectA)
         {
           "miss! $objectB"
           continue
         }
     else {
           "hit!  $objectB" 
           break
          }
   }
}

objectA: a
hit!  a
objectA: e
miss! a
miss! b
miss! c
miss! d
hit!  e
objectA: i
miss! a
miss! b
miss! c
miss! d
miss! e

Я бы использовал Do..до петли своего предназначения-это именно то, что вы описываете.

Function checkLists() {
  ForEach ($objectA in $listA) {
    $Counter = 0
    Do {
        $ObjectB = $listB[$Counter]
        #other stuff
    }
    #Keep going until we have a match or reach end of array
    Until (($objectA -eq $objectB) -or (($Counter+1) -eq $Listb.count()))
    }
}

вот простой пример:

#Example use of do..until
$i = 1
do {
  $i++
  write-host $i
  }
until ($i -eq 10)

это заняло у меня некоторое время, чтобы, наконец, получить его правильно. Надеюсь, что решение и пример помогут другим людям.

в этом приложении, мне нужно обрабатывать каждый узел и подузел как вложенные циклы. Ключ, похоже, получает относительные имена узлов в цикле foreach.

вот код:

[System.Xml.XmlDocument] $xml = new-object System.Xml.XmlDocument;
$xml.load("g:\tmp\down\order_01.xml");

foreach ( $order in $xml.SelectNodes("//orders/order"))
{
    # all these work
    $invoiceNumber = $xml.orders.order."invoice-no";                 
    $invoiceNumber = $order."invoice-no";                            
    $invoiceNumber = $order.SelectSingleNode("//invoice-no");        
    $invoiceNumber = $order.SelectSingleNode("./invoice-no");        
    $invoiceNumber = $order.SelectSingleNode("invoice-no");          

    foreach ($lineItem in $order.SelectNodes("product-lineitems/product-lineitem"))   #$xml.orders.order.'product-lineitems'.'product-lineitem')
    {
        $tax = $lineItem.tax;                             #works
        $tax = $lineItem.SelectSingleNode("tax");         #also works

        $name = $lineItem."product-name";
        write-host "Tax ", $tax, " name ", $name;

        foreach ( $optionItem in $lineItem.SelectNodes("option-lineitems/option-lineitem"))
        {
            $optionTax = $optionItem."tax";
            $optionId  = $optionItem."option-id";
            if ($optionId -eq 'engravingOption')
            {
#                $optionTax = $optionItem.SelectSingleNode("tax");
                Write-Host  "option Tax ",  $optionTax, " option id ", $optionId;
            }
        }
    }
}


And here is the sample xml:


<?xml version="1.0" encoding="UTF-8"?>      
<orders>xmlns="http://www.demandware.com/xml/impex/order/2006-10-31">
    <order order-no="00030562">     
        <invoice-no>00038012</invoice-no>   
        <product-lineitems> 
            <product-lineitem>      
                <tax>13.45</tax>    
                <product-name>Scoop Ice Bucket</product-name>       
                <option-lineitems>  
                    <option-lineitem>       
                        <net-price>7.00</net-price> 
                        <tax>11.11</tax>     
                        <option-id>includeGiftWrapping</option-id>  
                    </option-lineitem>      
                </option-lineitems> 
            </product-lineitem>     
            <product-lineitem>      
                <tax>22.22</tax>     
                <product-name>Love Bowl</product-name>      
                <option-lineitems>  
                    <option-lineitem>       
                        <tax>33.33</tax>     
                        <option-id>includeGiftWrapping</option-id>  
                    </option-lineitem>      
                    <option-lineitem>       
                        <tax>44.44</tax>     
                        <option-id>includeGiftWrapping</option-id>  
                    </option-lineitem>      
                </option-lineitems> 
            </product-lineitem>     
            <product-lineitem>      
                <tax>55.55</tax>    
                <product-name>Groove Decanter Set</product-name>    
                <option-lineitems>  
                    <option-lineitem>       
                        <tax>66.66</tax>     
                        <option-id>includeGiftWrapping</option-id>  
                    </option-lineitem>      
                </option-lineitems> 
            </product-lineitem>     
            <product-lineitem>      
                <tax>66.66</tax>     
                <lineitem-text>Klasp Cocktail Shaker</lineitem-text>
                <option-lineitems>  
                    <option-lineitem>       
                        <tax>77.77</tax>     
                        <option-id>includeGiftWrapping</option-id>  
                    </option-lineitem>      
                    <option-lineitem>       
                        <tax>88.88</tax>     
                        <option-id>engravingOption</option-id>      
                    </option-lineitem>      
                </option-lineitems> 
            </product-lineitem>     
        </product-lineitems>
    </order>
</orders>