Tuesday, July 15, 2008

Arrays in PowerShell

Sometimes PowerShell weirds me out a little bit because some parts look a lot like Perl, but don't act like it. There are a lot of bits and pieces strewn about the Web about how to use arrays and hashtables (I'll get to those later), but I had to look up several of them to get all of the information I wanted, so I'll lay them out here.

Arrays

An array is an ordered list of variables that can be accessed via their index.  It's a lot simpler than it sounds.  First, there are two ways to explicitly create an array:

PS C:\> [array]$my_list = (1, 7, 3, 19, 24, 2)
PS C:\> $my_list = @(1, 7, 3, 19, 24, 2)

Most people will just use the @() format.  This tells PowerShell to return whatever's between the parentheses as an array (even if there's only one member).

So let's take a look at our new array:

PS C:\> $my_list
1
7
3
19
24
2

PS C:\> $my_list.Length
6

PS C:\> $my_list[2]
3

Note that on that last one I used [2] at the end of the array object to denote that I want to grab the third object in the array.  The code below shows what the array looks like:

PS C:\> foreach ($index in (0 .. ($my_list.Length - 1))) {
>>  echo ("`$my_list[$($index)] = $($my_list[$index])")
>> }
>>
$my_list[0] = 1
$my_list[1] = 7
$my_list[2] = 3
$my_list[3] = 19
$my_list[4] = 24

Note the '..' operator above.  This is a handy range operator, especially when working with arrays.  When I'm reading it in my head, I think of it as the word 'through', as in:

PS C:\> $count = (1..10)

Which would read: "$count equals one through 10".  This creates an array where the first 10 elements are the numbers 1 through 10.

Let's say I only want the first three elements of the array:

PS C:\> $count[0..2]
1
2
3

Or maybe I only want elements 1, 4, and 5

PS C:\> $count[1, 4, 5]
2
5
6

Here's a slightly trickier one:  Maybe I only want the last three elements.  By using negative numbers, you can count from the last element backwards:

PS C:\> $count[-1 .. -3]
10
9
8

Now what if I want everything from the second element on?  Naturally I would think that this would work:

PS C:\> $count[1 .. -1]
2
1
10

That didn't do what I expected.  It seems to have counted backwards, giving me the second element, but instead counting ahead until it reached the -1 element, it counts backwards to reach -1, so instead of getting $count[1, 2, 3, 4, 5, 6, 7, 8, 9], I got $count[1, 0, -1].

We can do it, though; we have the technology:

PS C:\> $count[1 .. ($count.Length - 1)]
2
3
4
5
6
7
8
9
10

The Length or Count property of an array will give us the total number of elements in the array, but we have to subtract 1 because because arrays start with an index of 0.

One last thing before I wrap this up:  remember $my_list?  It's all out of order, so let's sort it.

$my_list = $my_list | sort

There.  Much better.

No comments: