Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested ForEach() in PowerShell

I'm having some troubles with nested ForEach loops in Powershell. First, I need to iterate through list 1. For every object in list 1, I need to iterate through list 2. When I found the resembling object in list 2, I want to go to the next object in list 1.

I've tried break, i've tried continue, but it won't work for me.

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) What does a break/continue exactly do in PowerShell?

b) How exaclty should I conquer my 'problem'?

like image 649
Jente Avatar asked Dec 31 '13 11:12

Jente


People also ask

What is nested ForEach?

Nesting ForEach Tags consists of creating two loops, an inner loop and an outer loop, such that for each item returned by the outer loop, the inner loop executes completely and returns its items associated to the outer loop's item.

What is ForEach-object in PowerShell?

The ForEach-Object cmdlet performs an operation on each item in a collection of input objects. The input objects can be piped to the cmdlet or specified using the InputObject parameter. Starting in Windows PowerShell 3.0, there are two different ways to construct a ForEach-Object command. Script block.

How do I break a ForEach loop in PowerShell?

Using break in loopsWhen a break statement appears in a loop, such as a foreach , for , do , or while loop, PowerShell immediately exits the loop. A break statement can include a label that lets you exit embedded loops. A label can specify any loop keyword, such as foreach , for , or while , in a script.


2 Answers

Use a label as described in 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

Like so,

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
like image 193
vonPryz Avatar answered Oct 08 '22 12:10

vonPryz


Here's an example using break/continue. Reverse the test in the inner loop, and use Continue to keep the loop going until the test fails. As soon as it gets a hit, it will break the inner loop, and go back to the next object in the outer loop.

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
like image 40
mjolinor Avatar answered Oct 08 '22 11:10

mjolinor