2

I am experimenting on two-dimensional arrays. I want some sort of a matrix, all with the same character. I can define a blank multi-dimensional array with fixed elements, and supply it with a character using loops. However, I can also do @(something)*n to directly define an array already supplied with something.

From what I understood so far, this is how to do it:

> $arr = ,(,'E'*3)*3

These seems alright:

> $arr[1]
E
E
E
> $arr[1][2]
E

But when I try to replace a character somewhere, like $arr[1][2] = 'D', many characters are replaced:

> $arr
E
E
D
E
E
D
E
E
D

Is my array definition wrong? Added: Then, how to correctly define it 'quickly'?

4
  • 4
    Your $arr contain same array three times, but not three separate arrays. Commented Jul 21, 2018 at 5:59
  • Thanks for reply. Do you know how to define the 'three separate arrays' thing 'quickly' like my (wrong) definition? Sorry for another question. Commented Jul 21, 2018 at 6:28
  • Possible duplicate of Powershell Multidimensional Arrays Commented Jul 21, 2018 at 6:39
  • @PetSerAl Thanks! Commented Jul 21, 2018 at 16:36

1 Answer 1

1

Using the * operator on non-numeric values creates copies of the original value. However, if the item you're copying isn't of a primitive(-ish) type like String or Char, the result will not be a duplicate of that object, but a copy of the object reference. Since all instances will then be pointing to the same object, changing one will change all.

To create distinct instances you need to repeat the array instantiation in a loop, as PetSerAl showed in the comments:

$arr = 1..3 | ForEach-Object { ,(,'E' * 3) }

In this particular case you could also create a "template" array and clone it:

$a0 = ,'E' * 3
$arr = 1..3 | ForEach-Object { ,$a0.Clone() }

Note, however, that cloning an object will not clone nested object references, so the latter is not a viable approach in all scenarios.

Something like this won't work the way you intend (because the references of the nested hashtable objects are still pointing to the same actual hashtables after cloning the array object):

PS C:\> $a0 = ([PSCustomObject]@{'x'='E'}),([PSCustomObject]@{'x'='E'})
PS C:\> $arr = 1..2 | ForEach-Object { ,$a0.Clone() }
PS C:\> $arr

x
-
E
E
E
E

PS C:\> $arr[1][1].x = 'F'
PS C:\> $arr

x
-
E
F
E
F

But something like this will work:

PS C:\> $arr = 1..2 | ForEach-Object { ,(([PSCustomObject]@{'x'='E'}),([PSCustomObject]@{'x'='E'})) }
PS C:\> $arr

x
-
E
E
E
E

PS C:\> $arr[1][1].x = 'F'
PS C:\> $arr

x
-
E
E
E
F
Sign up to request clarification or add additional context in comments.

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.