Converting to Array

When you run a PowerShell pipeline, that pipeline might return 0, 1 or many items.  If you are assigning the results of that pipeline to a variable, you will get $null, 1 item or an array of items respectively.  Sometimes, you won’t care about the different types returned, but at other times, you’ll actually prefer to force the results to always be an array.  In those cases, you can use @( … ).  As in:


$a = @(get-childitem)


 That will evaluate the statements enclosed within the parentheses and collect the results into an array.  If there are no results, then you’ll get an array of length zero. 


This usually works well enough, but I found that I usually decide that I want an array after I’m well into writing the pipeline.  I would then have to move the cursor back to the beginning of the pipeline, to insert the “@(“.  After repeating that enough times I got annoyed and decided I’d rather just append something at the end of the pipeline that would convert the results to an array.  Thus was born my ToArray function.


function ToArray
{
  begin
  {
    $output = @();
  }
  process
  {
    $output += $_;
  }
  end
  {
    return ,$output;
  }
}


Simple enough right?  The begin block creates a new empty array.  The process block, which gets called for every pipeline item, adds that item to the array, and the end block just puts the array into an array of length 1 and writes that array to the pipeline.  I need to wrap the $output array in a 1 element array because the pipeline will unravel all enumerables (well, almost all).  This way it just unravels that 1 element array and what’s left is my original array.


One thing you should know is that this isn’t exactly the most performant way to do this.  For every item I’m creating a brand new array.  If I was going to pipe a lot of items I would probably be better off using an ArrayList and converting it to an array at the end.  I’ll leave that part as an exercise for you.


This works for me.  It’s simple and it makes my life easier.  Now whenever I need to make the results into an array I just pipe into ToArray.  No more having to to go back to the beginning of the pipeline for me. 🙂


$a = get-childitem | ToArray


– Marcel Ortiz Soto [MSFT]


P.S. if ToArray is too long for you, create an alias.