Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList Unrolling

Tags:

powershell

Powershell unrolling is driving me crazy.

I have the following code to retrieve email addresses from an exchange recipient. I'm using the ArrayList because it is suggested by many people when you want the ability to remove items from the array.

$aliases = New-Object System.Collections.ArrayList
$smtpAddresses = (Get-Recipient $this.DN).EmailAddresses | ?{$_.Prefix.ToString() -eq 'smtp' } 
    foreach ($smtpAddress in $smtpAddresses) {
        $aliases.Add($smtpAddress.SmtpAddress)
    }
return $aliases

The value of $aliases is correct at the end of the function (i.e. will contain x email addresses and is type ArrayList) but after returning it becomes System.Object[] and has 2x entries. There x Int32's followed by x Strings (i.e. {0, 1, bob@here, bob@there} ). Why does this happen and how to I keep my ArrayList intact? Am I wrong for using ArrayList?

Out of curiosity, with all the questions/problems resulting from PS unrolling, what is its purpose? The big benefit of powershell is that you work directly with objects instead of their textual projections, unfortunately, I never know what kind of object I'm working with - and even when I check, it doesn't seem to hold its shape for more than a few lines of code.

-- Edit The function is called as part of a PSObject

$get_aliases = { ... }
$obj | Add-Member -MemberType ScriptProperty -Name Aliases -Value $get_aliases -SecondValue $set_aliases
like image 845
bob Avatar asked Oct 16 '12 14:10

bob


1 Answers

Part of the problem is how the array is being used inside the function. Remember, a function in PowerShell doesn't actually return anything. It writes objects to the pipeline. Therefore, the return is superfluous, but not actually causing any problems. The use of the Add function is causing the problem because Add returns the index at which the value was added and therefore writes to the pipeline as well.

function get-myarray
{ 
   $al = New-Object System.Collections.ArrayList
   $al.Add( 0 ) 
   $al.Add( 1 )
   $al.Add( '[email protected]' )
   $al.Add( 'you.co.com' )
   return $al 
}

$array = get-myarray
$array.Count
8     

Note how the size is 8. What needs to be done is to suppress the writing of what is returned by the Add function. There are a few ways to do this but here is one:

function get-myarray
{ 
   $al = New-Object System.Collections.ArrayList
   $al.Add( 0 ) | out-null
   $al.Add( 1 )  | out-null
   $al.Add( '[email protected]' )  | out-null
   $al.Add( 'you.co.com' )  | out-null
   return $al 
}

$array = get-myarray
$array.Count
4 

I don't believe the use of `ArrayList' is a wrong one if you want to remove items from it.

As far as unrolling goes, this deserves a whole other question and has been already addressed.

like image 73
Scott Saad Avatar answered Nov 16 '22 02:11

Scott Saad