PowerShell Tip: How to “shift” arrays…

PowerShell Tip: How to “shift” arrays…

  • Comments 14

It's fairly common in scripts to extract the first element out of an array then "shift" the remaining elements. Perl has a special shift operator for doing this as do many of the UNIX shells. PowerShell, however, doesn't have a shift operator built-in. So how do we shift arrays in PowerShell? Well – we could do it the brute force way and simply copy all of the elements after the first one but that sounds like too much work. A way to make it a bit easier is to use the range operator ('..') and array slices as shown:

 

$first = $oldArray[0]

$oldArray = $oldArray[1 .. ($oldArray.count-1)]

 

But that's still too much typing. In practice, PowerShell's multiple assignment feature is the most effective way to handle this kind of thing. Consider the following array:

 

PS (1) > $a = 1,2,3,4,5

 

We can use multiple assignment to split this array into $first and $rest simply by doing:

 

PS (2) > $first, $rest = $a

 

The first element from the array is placed into $first, the remaining elements are copies into $rest

 

PS (3) > $first

1

PS (4) > $rest

2

3

4

5

 

If we don't care about the first element, then we can use $null instead of $first and the value will simply be discarded.

 

PS (5) > $null, $rest = $rest

PS (6) > $rest

3

4

5

PS (7) >

 

This is actually a pretty handy approach to solving a variety of list restructuring problems. For example, say we have a list that looks like:

 

PS (7) > $list = "one",1,"two",2,"three",3

 

The form of this list is simply a name followed by a value:

 

PS (8) > $list

one

1

two

2

three

3

 

Now I want to "fold" that list into a hashtable as a set of key/value pairs. Here's a one-liner that will do this:

 

PS (9) > $hash = @{} ; while ($list) { $key, $value, $list = $list; $hash[$key]=$value }

 

The first two elements of the list go into $key and $value. The remaining elements are assigned back to $list. This loops until $list is empty. The resulting hash table looks like:

 

PS (10) > $hash

 

Name Value

---- -----

two 2

three 3

one 1

 

-bruce

   

Bruce Payette [MSFT]

Windows PowerShell Tech Lead

   

Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell

Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Windows PowerShell in Action (book): http://manning.com/powershell

 

Leave a Comment
  • Please add 3 and 5 and type the answer here:
  • Post
  • WOW!

    The implecations are mind-boggling.

    What does this mean to teh pipeline?

    Can we take pop one list and push another?

    This can be used for queuing problems I suspect.

  • "The first two elements of the list go into $key and $value. The remaining elements are assigned back to $list. This loops until $list is empty. The resulting hash table looks like: "

    Hmmm... not quite true is it, or the items would be in the same order as they were in $hash.

  • The hashtable class doesn't preserve the order in which elements are added. This is why the list displayed by dumping the hashtable looks different when compared to the original list.

    -bruce [MSFT]

  • Ooh, CAR & CDR. Nice. :)

    I can feel my LISP days coming back to me...

  • I think you should have a contact e-mail on your website.  Or maybe you are too busy...

    Anyways, I would like to request an opinion if Powershell can accomplish a particular solution.  Can Powershell be used to change the password (or entirely disable the account, or manipulate in general) of the local administrator accounts of computers in an Active Directory domain?

  • aaron - What you are asking for actually has nothing to do with Powershell. What you want to do is accomplished via the ADSI provider.

    It is exposed in PowerShell (see the PowerShell release notes). It is also exposed to traditional Windows Scripting Host and C/C++ APIs.

    //David

  • Aaron,

    So you want to do something like use AD to list the computers, then go to each computer and change the *local* Admin passwd?

  • Thanks for this tip. How would we push onto and pop from arrays? This is the same as shifting, but operates on the last value, not the 1st.

  • actually, in perl, shift/unshift push/pop are not operators - they are functions.  The "shift" operator you are missing however, is a bit-shift operator, which i desperately need at the moment...

  • the $null operator unfortunately is not as good as it sounds...

    > $a = 1,2,3,4,5

    > $a

    #returns 1

    #        2

    #        3

    #        4

    > $a.length

    # returns

    # 4

    > $a[0] = $null

    > $a

    # returns

    # 2

    # 3

    # 4

    > $a.length

    # still returns 4

    except that $a[0] cannot be referenced anymore...

  • Chris: it's like this one:

    > $a = $null, $null, $null, $null

    > $a

    > $a.Length

    4

    > $a[0] = 1

    > $a

    1

    You just have array of nulls. Nothing special. Except of course the special meaning of null value.

    David

  • if I'm trying to merge 2 arrays into 1 (I need to values in one property of an object placed into a different object) and both arrays share a key, how would I do mege them?

    e.g.  

    $username

    name                       title           employee      

    -------                    -------            --------------

    Smith, bob         carpenter       307

    $room

    employee            room

    ---------------            ---------

    307                          80

    How do I merge this into a single array / object with the name, title, room, employee properties ?            

  • Ok, I found this a little late and it is an awesome concept of doing things but why not create a shift function. Something that allows you to remove the first item from $args while maintaining the rest.

    function Shift ($tempItem) {

       $returnItem, $script:args = $tempItem

       $ReturnItem

    }

Page 1 of 1 (14 items)