2

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?

3 Answers 3

2
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

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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)

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.