web-dev-qa-db-fra.com

ForEach imbriqué () dans PowerShell

J'ai des problèmes avec les boucles ForEach imbriquées dans Powershell. Tout d'abord, je dois parcourir la liste 1. Pour chaque objet de la liste 1, je dois parcourir la liste 2. Lorsque j'ai trouvé l'objet ressemblant dans la liste 2, je veux passer à l'objet suivant dans la liste 1.

J'ai essayé de faire une pause, j'ai essayé de continuer, mais ça ne marchera pas pour moi.

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) Que fait exactement une interruption/poursuite dans PowerShell?

b) Dans quelle mesure dois-je vaincre mon "problème"?

12
Jente

Utilisez une étiquette comme décrit dans 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

Ainsi,

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
11
vonPryz

Voici un exemple utilisant break/continue. Inversez le test dans la boucle intérieure et utilisez Continuer pour maintenir la boucle jusqu'à ce que le test échoue. Dès qu'il obtient un coup, il cassera la boucle intérieure et retournera à l'objet suivant dans la boucle extérieure.

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
4
mjolinor

J'utiliserais une boucle Do..until - son utilisation prévue est exactement ce que vous décrivez.

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()))
    }
}

Voici un exemple simple:

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