1

I have a powershell nested array with the below structure.

$jHosts = @(@("Host-1","Host-3"),@("Host-2","Host-4"),@("Host-5"))

As well as here is my powershell script to iterate the nested array.

    for($i=0; $i -le $jHosts.Length; $i++){  
        Write-Host $jHosts[$i]  
        for($k=0;$k -le $jHosts.Length; $k++){  
            Write-Output $jHosts[$i][$k]
        }
    }

The Write-output displays the output like below,

HOST-1
HOST-3
HOST-2
HOST-4
H
O
S
T

As my for loops reads all the values in first 2 nested arrays but it reads each character of a 3rd array's string when it is a single object. What am I doing wrong here?

stackprotector
  • 10,498
  • 4
  • 35
  • 64
  • Does this answer your question? [Pipe complete array-objects instead of array items one at a time?](https://stackoverflow.com/questions/29973212/pipe-complete-array-objects-instead-of-array-items-one-at-a-time) – iRon Dec 15 '20 at 07:20
  • Have you accidentally set `$ErrorActionPreference ='SilentlyContinue'`? On my machine, Powershell shows several index errors if I run the above code. – zett42 Dec 15 '20 at 08:27

2 Answers2

0

I am not able to reproduce your result, but your code contains two logical errors anyway:

  1. You disregard the actual array boundaries by using the -le operator in your loop definitions. Use -lt instead.

  2. You use the wrong length for your nested arrays. Replace $jHosts.Length by $jHosts[$i].Length in your "k" loop.

This is how your code seems to produce a valid result:

$jHosts = @(@("Host-1","Host-3"),@("Host-2","Host-4"),@("Host-5"))

for($i=0; $i -lt $jHosts.Length; $i++){  
    Write-Host $jHosts[$i]  
    for($k=0;$k -lt $jHosts[$i].Length; $k++){  
        Write-Output $jHosts[$i][$k]
    }
}

Output:

Host-1 Host-3
Host-1
Host-3
Host-2 Host-4
Host-2
Host-4
Host-5
Host-5
stackprotector
  • 10,498
  • 4
  • 35
  • 64
0

To iterate through an array, use the Count property, rather than the Length. In your case, because the last element in the array has only one item, it will be unwrapped by PowerShell to act as the single string "Host-5".

If you do "Host-5".Length the answer is 6 (6 characters in the string)
If you do "Host-5".Count the answer is 1 (just one single string)

Also, you are iterating one level too deep by doing -le, that should be -lt since you start iterating at 0.

$jHosts = @(@("Host-1","Host-3"),@("Host-2","Host-4"),@("Host-5"))
for($i=0; $i -lt $jHosts.Count; $i++){  
    for($k=0;$k -lt $jHosts[$i].Count; $k++){  
        Write-Output $jHosts[$i][$k]
    }
}

Returns

Host-1
Host-3
Host-2
Host-4
Host-5

If I add the extra line Write-Host $jHosts[$i] as in your code and do

$jHosts = @(@("Host-1","Host-3"),@("Host-2","Host-4"),@("Host-5"))
for($i=0; $i -lt $jHosts.Count; $i++){  
    Write-Host $jHosts[$i]
    for($k=0;$k -lt $jHosts[$i].Count; $k++){  
        Write-Output $jHosts[$i][$k]
    }
}

the result is

Host-1 Host-3
Host-1
Host-3
Host-2 Host-4
Host-2
Host-4
Host-5
Host-5
Theo
  • 57,719
  • 8
  • 24
  • 41