user3517375
user3517375

Reputation: 91

Powershell add element to each array in multidimensional array

Finding out how much fun arrays in PowerShell are compared to other languages.

Here's what I start with: $testArr = (1,2,3),(4,5,6)

Here's what I want to end up with: (1,2,3,0),(4,5,6,0)

And what I've tried to get it: foreach($x in $testArr) { $x += 0 } and $testArr | % { $_ += 0 }

However, when I try to output $testArr, I get what I started with: (1,2,3),(4,5,6). I put a call to output the current array being worked with in the loop and see the 0 is in the array after adding it (+= 0), but for some reason, it doesn't want to stick around when I output the 2-D array. What aspect of PowerShell arrays am I missing?

Upvotes: 2

Views: 2876

Answers (3)

js2010
js2010

Reputation: 27626

I'll do it close to your way, with the caveat that += kills puppies. I guess you didn't have the direct reference to the arrays.

foreach ($i in 0,1) { $testarr[$i] += 0 }
$testarr

1
2
3
0
4
5
6
0

You could also make it an array of 2 arraylists.

$a = [Collections.ArrayList](1,2,3),[Collections.ArrayList](4,5,6)
$a[0].add(0)
$a[1].add(0)

Upvotes: 0

AdminOfThings
AdminOfThings

Reputation: 25061

iRon's helpful answer describes the crux of the problem and that is arrays cannot be resized. If you want to add to a collection, you must choose a collection type that allows the length to be changed. Some common re-sizable types include generic lists and arraylists. An approach to allow you to change the size of a multi-dimensional collection could be to have an [arraylist] object that contains generic lists of [int] objects.

[collections.arraylist]$testArr = [collections.generic.list[int]](1,2,3),[collections.generic.list[int]](4,5,6)

$testArr
1
2
3
4
5
6

$testArr.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ArrayList                                System.Object

$testArr[0]
1
2
3

$testArr[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     List`1                                   System.Object

$testArr[0].Add(0)
$testArr[0]
1
2
3
0

$testArr[1].Add(0)
$testArr[1]

4
5
6
0

You can now refer to each sub-collection by their indexes [0] and [1] and augment them accordingly.

Upvotes: 0

iRon
iRon

Reputation: 23862

For ($i = 0; $i -lt $testArr.Count; $i++) {$testArr[$i] += 0}

The point is that the arrays are actually of a fixed size.
Prove:

foreach($x in $testArr) { $x.Add(0) }

Exception calling "Add" with "1" argument(s): "Collection was of a fixed size." At line:1 char:27
+ foreach($x in $testArr) { $x.Add(0) }
+ ~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException

In other words, when you use the += assignment operator, you're actually creating a copy of the array and reassigning this to the variable.
Prove:

PS C:\> $a = 1,2,3
PS C:\> $b = $a
PS C:\> $a += 4
PS C:\> $a
1
2
3
4
PS C:\> $b
1
2
3

Meaning, you're creating a copy of $x which is no longer a reference to the items in the $testArr

Upvotes: 2

Related Questions