Reputation: 856
I have implemented a simple merge sort function in PowerShell like so
function Merge-Sort
{
param($a)
if ($a.Length -gt 1)
{
$m = [Math]::floor($a.Length / 2)
[Int[]]$l = $a[0..($m-1)]
[Int[]]$r = $a[$m..($a.Length)]
Merge-Sort $l
Merge-Sort $r
$i = $j = $k = 0
while ($i -lt $l.Length -and $j -lt $r.Length)
{
if ($l[$i] -lt $r[$j])
{
$a[$k] = $l[$i]
$i++
}
else
{
$a[$k] = $r[$j]
$j++
}
$k++
}
while($i -lt $l.length)
{
$a[$k] = $l[$i]
$i++
$k++
}
while($j -lt $r.length)
{
$a[$k] = $r[$j]
$j++
$k++
}
}
}
The functions does what it should and sorts an array of integer values:
$arr = @(22,44,55,11,66,11,77,99,33,88)
merge-sort $arr
The output is: 11 11 22 33 44 55 66 77 88 99
But when I define the function parameter as [Int[]] to make clear that it should be an array of integers instead of object something went wrong and the array stays unsorted:
function Merge-Sort
{
param([Int[]]$a)
...
}
The output is: 22 44 55 11 66 11 77 99 33 88
My question is:
Why does the correct way to define the function parameter leads to an incorrect result (the array does not get sorted)?
Upvotes: 1
Views: 2639
Reputation: 6860
When the object $arr is created since it wasn't defined as a int array [int[]] it was created as a [array]. When passed to the function originally before [int[]] was added. It passed the reference and changed the data. If you Added a addition object to the array it would have not returned anything ether since that would have created a new array object.
When you added the [int[]] to the parameter it created a brand new int array [int[]] object named $a and changed the data there. Since $a is never return the variable is killed at the end of the function.
If you passed a int array it would have manipulated that array.
Lets looks over a few examples
This will change the first value at index 0 to 5. Since no object was added to the array and the array can be any object in the parameter it allowed the reference to index 0 to be changed instead of a whole new object needing to be returned
function TestFunction($a)
{
$a[0] = 5
}
$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar
output 5,3,1
Since the orignal object is type Array and the parameter is type int array. the function will create a new int array based on the input array. Since the function needs to return the new int array and there is no return it will be garbage collected.
function TestFunction([int[]]$a)
{
$a[0] = 4
}
$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar
So in your case we can do
function TestFunction([int[]]$a)
{
$a[0] = 4
}
[int[]]$TestVar = @(2,3,1)
TestFunction -a $TestVar
$TestVar
since the parameter is looking for a int array and the input is a int array and no new objects are being added or subtracted from the array it will change the value correctly.
Upvotes: 2