15

I want to create an empty array of arrays in Powershell to hold "tuples" of values (arrays are immutable).

Therefore I try something like:

The type of $arr is Object[]. I've read that += @(1,2) appends the given element (i.e. @(1,2)) to $arr (actually creates a new array). However, in this case it seems that the arrays are concatenated, why?

$arr = @()
$arr += @(1,2)
$arr.Length // 2 (not 1)

If I do as follows, it seems that $arr contains the two arrays @(1,2),@(3,4), which is what I want:

$arr = @()
$arr += @(1,2),@(3,4)
$arr.Length // 2

How do I initialize an empty array of arrays, such that I can add one subarray at a time, like $arr += @(1,2)?

0

4 Answers 4

17

The answer from Bruce Payette will work. The syntax seems a bit awkward to me, but it does work. At least it is not Perl.

Another way to do this would be with an ArrayList. To me, this syntax is more clear and more likely to be understood by another developer (or myself) in six months.

[System.Collections.ArrayList]$al = @()

$al.Add(@(1,2))
$al.Add(@(3,4))

foreach ($e in $al) {
    $e
    $e.GetType()
}
6

The + operator concatenates arrays. To add an array as a single element, prefix the element to add with a comma. Something like @() + , (1,2) + , (3, 4).

3

As far as I can tell, you can't do it natively in PowerShell, nor can you do it with the [System.Array] type. In both cases, you seem to need to define both the length and the type of the array. Because I wanted a completely empty array of arrays, with the ability to store any type of value in the array, I did it this way.

$x=[System.Collections.ArrayList]::new()
$x.Count
$x.GetType()

$x.Add([System.Collections.ArrayList]::new()) > $null
$x.Count
$x[0].Count
$x[0].GetType()

$x[0].Add("first element") > $null
$x.Count
$x[0].Count
$x[0][0]
0

An array of untyped arrays, having a length of 0:

$UntypedAoAs = [array[]]::new(0)
$UntypedAoAs.Length # Returns 0

Appending to an array of untyped arrays:

$UntypedAoAs += , ('a', 1)
$UntypedAoAs += , ('b', 2)
$UntypedAoAs += , ('c', 3)
$UntypedAoAs.Length     # Returns 3
$UntypedAoAs[0]         # Returns 'a' and 1
$UntypedAoAs[0].Length  # Returns 2
$UntypedAoAs[2][0]      # Returns 'c'

Verifying the type of elements:

$UntypedAoAs[0][0].GetType() # String type
$UntypedAoAs[0][1].GetType() # Int32 type

You can replace [array[]] with [string[][]], but it appears that this will NOT restrict/prevent appending arrays of any type you want.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.