1

I am attempting to construct an array of array of strings but there is an issue if i creates an array with only one sub array, it seens to somehow becomes an array of array of characters?

But if i pass in 2 or more sub arrays either hard coded or from a variable it works as expected

I need to pass this into a custom function which i then iterate over but due to the weird way that the single sub array it completley fails

Edit: Since this is apparently still not easy enough to understand here's more info, Also missed some of the test code which included the 4 and 5 tests which i've fixed.

If you look at Test 4a and 4b that's what the results are for a single sub array of strings, as you can see it's not working as expected, what should happen is that 4a should be the same as 5a 4b should create an index out of bounds exception.

Here's my Test Code:

$Maps = [string[]]::new(5)
$Maps[0] = 'Ireland'
$Maps[1] = 'Scotland'
$Maps[2] = 'England'
$Maps[3] = 'Germany'
$Maps[4] = 'France'

$Maps2 = [string[]]::new(5)
$Maps2[0] = 'Japan'
$Maps2[1] = 'Crete'
$Maps2[2] = 'USA'
$Maps2[3] = 'Canada'
$Maps2[4] = 'Greece'

$Array = @($Maps)

Write-Host 'These results seem to treat a single variable as character arrays?'

Write-Host Test 1a: $Array[0][0]
Write-Host Test 1a: $Array[0][1]
Write-Host Test 1b: $Array[1][0]
Write-Host Test 1b: $Array[1][1]
Write-Host Test 1c: $Array[2][0]
Write-Host Test 1c: $Array[2][1]

$Array = @($Maps, $Maps2)

Write-Host 'These results seem to create the correct results'

Write-Host Test 2a: $Array[0][0]
Write-Host Test 2a: $Array[0][1]
Write-Host Test 2b: $Array[1][0]
Write-Host Test 2b: $Array[1][1]
Write-Host Test 2c: $Array[2][0]
Write-Host Test 2c: $Array[2][1]

$Array = @($Maps, @('Test1', 'test2'))

Write-Host 'These results seem to create the correct results'

Write-Host Test 3b: $Array[0][0]
Write-Host Test 3b: $Array[0][1]
Write-Host Test 3c: $Array[1][0]
Write-Host Test 3c: $Array[1][1]
Write-Host Test 3d: $Array[2][0]
Write-Host Test 3d: $Array[2][1]

$Array = @(@('Available Maps', 'Scotland', 'England', 'Germany', 'France'))

Write-Host 'Same Issue as First Example'

Write-Host Test 4a: $Array[0][0]
Write-Host Test 4a: $Array[0][1]
Write-Host Test 4b: $Array[1][0]
Write-Host Test 4b: $Array[1][1]

$Array = @(@('Available Maps', 'Scotland', 'England', 'Germany', 'France'), @('Test1', 'test2'))

Write-Host 'Works as Expected'

Write-Host Test 5a: $Array[0][0]
Write-Host Test 5a: $Array[0][1]
Write-Host Test 5b: $Array[1][0]
Write-Host Test 5b: $Array[1][1]

Here's the Results

These results seem to treat a single variable as character arrays?
Test 1a: I
Test 1a: r
Test 1b: S
Test 1b: c
Test 1c: E
Test 1c: n
These results seem to create the correct results
Test 2a: Ireland
Test 2a: Scotland
Test 2b: Japan
Test 2b: Crete
Cannot index into a null array.
At line:34 char:5
+     Write-Host Test 2c: $Array[2][0]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

Cannot index into a null array.
At line:35 char:5
+     Write-Host Test 2c: $Array[2][1]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

These results seem to create the correct results
Test 3b: Ireland
Test 3b: Scotland
Test 3c: Test1
Test 3c: test2
Cannot index into a null array.
At line:45 char:5
+     Write-Host Test 3d: $Array[2][0]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

Cannot index into a null array.
At line:46 char:5
+     Write-Host Test 3d: $Array[2][1]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

Same Issue as First Example
Test 4a: A
Test 4a: v
Test 4b: S
Test 4b: c
Works as Expected
Test 5a: Available Maps
Test 5a: Scotland
Test 5b: Test1
Test 5b: test2

Thanks

7
  • 1
    Very hard to tell where exactly you're looking for help or looking to understand. Commented Mar 13, 2022 at 20:33
  • @SantiagoSquarzon If you look at Test 4a and 4b that's what the results are for a single sub array of strings, as you can see it's not working as expected, what should happen is that 4a should be the same as 5a 4b should create an index out of bounds exception Commented Mar 13, 2022 at 20:35
  • There is no 4 and 5 in your code it goes up to 3 Commented Mar 13, 2022 at 20:38
  • 1
    You need to add a unary operator in your 4th example @( , @( ... )) or a new empty array @( @(), @(..)) if I understood correctly what you're looking for. Commented Mar 13, 2022 at 20:51
  • 1
    Adding a , before the first item as you suggested seems to have fixed it @(,$Maps) works as expected now, not an intuitive fix as no other language has that issue, thanks. Commented Mar 13, 2022 at 20:57

2 Answers 2

1

On the example 4a and 4b if you want to have an array with 2 nested arrays you coulduse an inner empty array subexpression operator @():

$Array = @(@(), @('Available Maps', 'Scotland', 'England', 'Germany', 'France'))
$Array[0]    # => Is an empty `System.Array`
$Array[1]    # => Is the populated `System.Array`
$Array[1][0] # => Available Maps

If you want the above example to throw an out of bounds exception, you would use $null instead:

$Array = @($null, @('Available Maps', 'Scotland', 'England', 'Germany', 'France'))
$Array[0]    # => Is `$null`
$Array[0][0] # => Is Out of Bounds
$Array[1]    # => Is the populated `System.Array`
$Array[1][0] # => Available Maps

With the Comma operator , you can create a nested array at index 0 of your parent array:

$Array = @(, @('Available Maps', 'Scotland', 'England', 'Germany', 'France'))
$Array[0]    # => Is the populated `System.Array`
$Array[0][0] # => Available Maps
$Array[1][0] # => Is Out of Bounds

Note that, in all these examples, the parent @() is not needed, PowerShell can dynamically assume this for you:

$Array = @(), @('Available Maps', 'Scotland', 'England', 'Germany', 'France')
$Array = $null, @('Available Maps', 'Scotland', 'England', 'Germany', 'France')
$Array = , @('Available Maps', 'Scotland', 'England', 'Germany', 'France')

As a personal opinion, I find hash tables more appropriate for this. For example, the first code snippet would be:

$hash = @{
    Array0 = @()
    Array1 = 'Available Maps', 'Scotland', 'England', 'Germany', 'France'
}

$hash['array0']    # => Is an empty `System.Array`
$hash['array1']    # => Is the populated `System.Array`
$hash['array1'][0] # => Available Maps
Sign up to request clarification or add additional context in comments.

Comments

0

In general I don't get why people prefer working with hash-tables (key+value) or nested objects (multiple info) over simple oldschool arrays (values only) - maybe I'm a bit olfashioned?

$collection does hold multiple $items with multiple keys+values each.

Foreach ($item in $collection) {
    [array]$arrayOfIdentifiers += ,@($item.Id,$item.Name)
}

$arrayIdentifier will be a fine simple classic array with two columns and multiple rows that can be accessed by:

$arrayOfIdentifiers[0][0]
$arrayOfIdentifiers[0][1]
$arrayOfIdentifiers[1][0]
$arrayOfIdentifiers[1][1]
[...]
$arrayOfIdentifiers[n][n]

The PowerShell way to create and add to arrays IMHO is very crude compared to other languages.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.