Arrays and generic collections in Powershell

As I noted in my last post, Powershell likes to make arrays.

But it’s been noted that using arrays can be horribly inefficient when it comes to adding or removing items from them, and collections work much better for those operations. The method you normally see to get a collection instead of an array is to instantiate a particular collection type, and then iterate through some objects using the .add() method of the collection to populate it.

In a previous post about script blocks I noted that the Invoke() method of a script block makes the script block return a collection.

$col = {get-process}.invoke()
$col.gettype()


IsPublic IsSerial Name                                     BaseType                                  
-------- -------- ----                                     --------                                  
True     True     Collection`1                             System.Object                             

If you research that collection type, it’s basically just a generic collection of PS objects. Since it’s a generic collection, it can contain any type of objects so the methods it offers is limited to basic methods for adding, removing, and inserting elements.


Get-Member -InputObject $col -MemberType Method | ft



   TypeName: System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSObject, 
System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]

Name          MemberType Definition                                                                  
----          ---------- ----------                                                                  
Add           Method     void Add(psobject item), void ICollection[psobject].Add(psobject item), i...
Clear         Method     void Clear(), void ICollection[psobject].Clear(), void IList.Clear()        
Contains      Method     bool Contains(psobject item), bool ICollection[psobject].Contains(psobjec...
CopyTo        Method     void CopyTo(psobject[] array, int index), void ICollection[psobject].Copy...
Equals        Method     bool Equals(System.Object obj)                                              
GetEnumerator Method     System.Collections.Generic.IEnumerator[psobject] GetEnumerator(), System....
GetHashCode   Method     int GetHashCode()                                                           
GetType       Method     type GetType()                                                              
IndexOf       Method     int IndexOf(psobject item), int IList[psobject].IndexOf(psobject item), i...
Insert        Method     void Insert(int index, psobject item), void IList[psobject].Insert(int in...
Remove        Method     bool Remove(psobject item), bool ICollection[psobject].Remove(psobject it...
RemoveAt      Method     void RemoveAt(int index), void IList[psobject].RemoveAt(int index), void ...
ToString      Method     string ToString()  

Most of the time this is all your really need.

You’ll note that there is no .ToArray() method, but remembering Powershell’s propensity for turning things into arrays it’s relatively trivial to get it to do that for you:

$col | set-variable col
$col.GetType()


IsPublic IsSerial Name                                     BaseType                                  
-------- -------- ----                                     --------                                  
True     True     Object[]                                 System.Array                              

So you can go back and forth between an array and a generic collection quite easily:


$array = get-process

$collection = {$array}.invoke()
$collection | set-variable array

$array.gettype()
$collection.GetType()


IsPublic IsSerial Name                                     BaseType                                  
-------- -------- ----                                     --------                                  
True     True     Object[]                                 System.Array                              
True     True     Collection`1                             System.Object                             

Advertisements

3 responses to “Arrays and generic collections in Powershell

  1. Is that a V2 feature or did it come later?

  2. Pingback: More on generic collections in Powershell V4, and a gotcha. | The Powershell Workbench

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s