Powershell: How to modify an array in the parent scope from within a function
-
Wednesday, January 09, 2013 6:19 PM
I'm writing a function that creates an array, and inside a second function called from the first, I want to add values to the array. I found a way to make it work, but it seems "costly" since I believe it recreates the array from scratch every time I add to it. I read about a way to pass the array as a [ref], but it looks more complicated that I thought it should be. Is there a better way to do this, or is this the right way to do it and the additional overhead of recreating the array is so small I shouldn't worry about it?
I guess I am really asking if there is a way to use the <variable> += <string> method of adding to the array, but have it act on the parent scope?
Thanks for your input.
TestFunctionScope.ps1:
function Calling-Function { Test-Function } function Test-Function { $MyArray = ("aaa", "bbb", "ccc") function AddToArray ($String1, $String2) { set-variable MyArray ($MyArray + ($String1)) -scope 1 # 3 other attempts to add a string to the array -- None of these add the string to the parent scope's variable $MyArray += $String2 $Script:MyArray += $String2 $Global:MyArray += $String2 } AddToArray "ddd" "eee" "Contents of Array after running AddToArray Function:" $MyArray }Output:
PS C:\~Working> . .\TestFunctionScope.ps1 PS C:\~Working> Calling-Function Contents of Array after running AddToArray Function: aaa bbb ccc ddd PS C:\~Working>
- Edited by Vizoere1 Wednesday, January 09, 2013 6:21 PM Added "Powershell" to title
All Replies
-
Wednesday, January 09, 2013 6:54 PMModerator
Hi,
You can also use the [Ref] type accelerator; e.g.:
function AppendTo-Array([Ref] $theArray, $newItem) { $theArray.Value += $newItem } $arr = "a","b","c" AppendTo-Array ([Ref] $arr) "d" $arr # now contains "a","b","c","d"
Bill
-
Wednesday, January 09, 2013 7:05 PMModerator
Adding to an array always creates a new array, regardless of whether it's done from within a function or not.
For a few elements the overhead is trivial. If you have to do a lot of it, switch to an arraylist
You have to use the .add() method on an arraylist instead of the += operator, but because it doesn't create a new object you don't have to scope it inside the function:
$arraylist = new-object collections.arraylist function test { [void]$arraylist.add('one') [void]$arraylist.add('two') [void]$arraylist.add('three') } test $arraylist
[string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "
- Edited by mjolinorMicrosoft Community Contributor, Moderator Wednesday, January 09, 2013 7:06 PM
- Marked As Answer by Vizoere1 Wednesday, January 09, 2013 7:54 PM
-
Wednesday, January 09, 2013 7:10 PMModerator
Hi,
mjolinor is correct about the overhead; I wasn't paying attention very well. I agree that the ArrayList object can be more efficient if you're appending very frequently. You can always test two versions (standard array, += operator) and the ArrayList object using Measure-Command to see which is more efficient.
Bill
-
Wednesday, January 09, 2013 7:56 PMThanks for the note about it always creating a new array. That answers my immediate question. However I'm sure to need large arrays in other scripts so the info about arraylist is appreciated as well!
-
Wednesday, January 09, 2013 7:57 PMI hadn't seen measure-command before. That's pretty awesome. Thanks Bill!

