I am using PowerShell 2.0. When I make a new variable as an array and then set another variable to be equal to the first one, the second variable "mirrors" the first one. After changing an object in the original array, the exact same change appears in the second array. For instance,
$array0001 = 6, 7, 3, 4, 0
$array0002 = $array0001
$array0001[3] = 55
$array0002
with the output being
6
7
3
55
0
I notice that when you set the second variable to have the same value as the first variable, except this time enclosed within a subexpression operator, modifications to the first array do not affect the second array. For instance,
$array0001 = 6, 7, 3, 4, 0
$array0002 = $($array0001)
$array0001[3] = 55
$array0002
with the output being
6
7
3
4
0
Why does enclosing the value in a subexpression operator change the behavior of the variable? Is there another or better way to avoid making array variables that "mirror" each other?
ETA: I have now found that $array0002 = @($array0001)
and $array0002 = &{$array0001}
both accomplish the exact same objective.
Array subexpression operator @( )Returns the result of one or more statements as an array. The result is always an array of 0 or more objects. PowerShell Copy.
To create and initialize an array, assign multiple values to a variable. The values stored in the array are delimited with a comma and separated from the variable name by the assignment operator ( = ). The comma can also be used to initialize a single item array by placing the comma before the single item.
You can also use PowerShell to compare arrays using the Compare-Object cmdlet. This cmdlet takes a reference object and a difference object and returns a side indicator indicating which elements are and are not in either array. You can see below that the Compare-Object cmdlet allows you to compare both arrays at once.
The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.
It's called "pass by reference". Instead of actually assigning a value, you're assigning a reference to another location that holds a value. If the value in the original location changes, the reference you made is pointing to that original location, and will see the updated value.
Most languages have ways to "pass by reference" and "pass by value". That's what you found by doing $array0002=$($array0001)
. Neither one is better than the other, they just both have different uses.
In PowerShell you can also put .value
behind your reference to grab the value, instead of the reference.
When setting one array equal to another like that, the different variables are simply referencing eachother, it's not a true copy. This is essentially the same thing that you are asking. From that link, serializing the data to do a deep copy is a good way around it.
#Original data
$Array1
# Serialize and Deserialize data using BinaryFormatter
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $Array1)
$ms.Position = 0
#Deep copied data
$Array2 = $bf.Deserialize($ms)
$ms.Close()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With