Archive for the “Array” Category

During the Scripting Games I found myself creating a lot of custom objects with properties that I could use to sort , select, take averages of, and a number of other cool things. Getting results into a Powershell object can make life a lot easier for a number of reasons.

There was one little piece I was missing. Not only did I want to create a single object, quite often I would want to put all the objects I created into a collection of objects. Did you know you can add collections of like objects to each other ?

   1: PS 13 >  $a = get-process

   2: PS 14 >  $a.count

   3: 66

   4: PS 15 >  $b = get-process

   5: PS 16 >  $c = $a + $b

   6: PS 17 >  $c.count

   7: 131

   8: PS 18 >

The code above shows that I can add two collections of process objects together. Very cool.

So I tried doing this in the scripting games and came across a problem. For instance, in Event 3 we needed to tally up a bunch of votes. So what I really needed was to create a bunch of $vote objects and put them all together in a collection called $votes

Here’s what I came up with at first.

By the way, when I create PS Custom Objects I cheat and use the “” | Select-Object prop1, prop2 nomenclature. My easier than using new-object followed by a bunch of add-member commands.

   1: $votes = "" | Select-Object v1,v2,v3,v4

   2: foreach ($v in Get-Content votes.txt)

   3:     {    

   4:         $vote = "" | Select-Object v1,v2,v3,v4;

   5:         $vote.v1,$vote.v2,$vote.v3,$vote.v4 = $v.split(",")

   6:         $votes += $vote

   7:     } 

Looks nice and shiny until you run it :) I get the following error:

Method invocation failed because [System.Management.Automation.PSObject] doesn’t contain a method named ‘op_Addition’.

Not so shiny

The trick is that we $votes needs to be a collection of $vote objects, not another object identical to $vote.

So we instantiate $votes with a cast to [array] and life is good.

   1: $votes = @()

   2: foreach ($v in Get-Content votes.txt)

   3:     {    

   4:         $vote = "" | Select-Object v1,v2,v3,v4;

   5:         $vote.v1,$vote.v2,$vote.v3,$vote.v4 = $v.split(",")

   6:         $votes = $votes + $vote

   7:     } 

A quick update, thanks to Aleksandar. We should instantiate $votes as $votes = @(). I have updated the example above.

Comments 3 Comments »

Powershell can slice and dice arrays all day long, and we use them all the time. However, when we are testing stuff and creating dummy arrays the syntax can be a bit awkward. Its quite straightforward and understandable, but its just a pain to type

For example

   1: PS 39 >  $i = "one","two","three"
   2: PS 40 >  $i
   3: one
   4: two
   5: three

Now for me that is just way too many quotes and commas. This can easily be addressed with a new function called New-Array.  Are we going to have to parse and add quotes and do all kinds of crazy stuff to get this working ? Not really. Here’s the function and how to use it.

   1: PS 41 >  function new-array {$args}
   2: PS 42 >  $i = new-array one two three four five six
   3: PS 43 >  $i
   4: one
   5: two
   6: three
   7: four
   8: five
   9: six

Ah, now that is much better. All this does is return the $args array which is an array that you get in every function be default. $args[0] is the first argument. $args[1] is the second etc etc.

That being said we are not quite there.  Lets say you want to be really sure you create an Array. In the case where you originally have only 1 $arg it will return a scalar. Let me demonstrate.

   1: PS 58 >  function new-array {$args}
   2: PS 59 >  $i = new-array 1
   3: PS 60 >  $i += 2
   4: PS 61 >  $i
   5: 3

 

In this case, $i ends up being a scalar with a value of 1 and then when you add 2 to it, you get $i = 3.

What we want is to be able to use the += operator to add a value to the array. There are multiple ways to force a scalar to be an array when you declare it but i think the comma operator is the shortest.  So we make one quick addition to our new-array function.

   1: PS 62 >  function new-array {,$args}
   2: PS 63 >  $i = new-array 1
   3: PS 64 >  $i +=2
   4: PS 65 >  $i
   5: 1
   6: 2

Pretty cool!

Comments 3 Comments »