We help IT Professionals succeed at work.

PowerShell - Array of arrays

PC_User321
PC_User321 asked
on
Medium Priority
10,272 Views
Last Modified: 2008-01-30
I have data in a pipeline from which I want to create an array of arrays like, for example:
  (a, XXa), (b, XXb), (c, XXc)
I don't want to use a pre-declared multi-dimensional array because it is messy and I don't know in advance how big it will need to be.

This code does not work - is gives a length of 6
$arrayOfArrays = ("a","b","c") | %{($_, "XX$_")}
# Check if it worked:
"arrayOfArrays[2] = " + $arrayOfArrays[2]
"Length = " + $arrayOfArrays.length


This code works but it is messy:
$tmp = @(1)
$arrayOfArrays = @()

("a","b","c") | %{ $tmp[0] = ($_, "XX$_"); $arrayOfArrays += $tmp;}
# Check if it worked:
"arrayOfArrays[2] = " + $arrayOfArrays[2]
"Length = " + $arrayOfArrays.length

Is there a better way?
Comment
Watch Question

Commented:
Why do you think you will need a multi-dimensional array

Simply put in Powershell it just doesn't seem needed. You can already nest arrays.

$MyBaseArray = @()
1..10 | %{$internalArray = 11..20;$MyBaseArray += $internalArray}
$MyBaseArray

Perhaps if I better understand what your attempting I can help.

Commented:
I been looking at this I think a hash table is perfect (if understand where your going)

Let me know if this is what your looking for

$data = @{}
("a","b","c") | foreach{$data.$_ = "xx$_"}
$data

Output:
Name                       Value                                                                                  
----                           -----                                                                                  
a                              xxa                                                                                    
b                              xxb                                                                                    
c                              xxc  

Author

Commented:
Thanks for your comment, BSonPosh.
My question is not about how to get a particular task accomplished, but rather a complain about what looks like a limitation of the language.

In my example I have an array to which I want to add (a, XXa), but I need a way of indicating to PowerShell that those 2 elements should be added as ONE ARRAY, and not as two separate thing.
And this way of indicating to PowerShell should work in a pipeline situation as I have shown in my example.

On page 71 of "PowerShell In Action", Bruce Payette says:
"Here is how array literals are defined in PowerShell: They're not. There is no array literal notation in PowerShell. .... If you need an array, one will be created for you."

Well, Bruce, in my first example I needed an array and one was NOT created for me.
I feel that PowerShell SHOULD have an array literal, like Perl has.
Or perhaps there is an elegant way of achieving this that I haven't figured out.

The essence of my question is, in my context (with a pipeline) how do I tell PowerShell that I want to add one array, not two array elements.

Thanks.

Commented:
I will pass this on to Bruce and the team and get a"Devish" answer.

You can create a literal Array by doing this
$tmp = @()

I think the problem is that Powershell sees two arrays and instead of adding one array to the other it seems to join them.

I do this all the time with custom objects, but I haven't tried specifically with two arrays.
Commented:
Two fellow MVPs provided this explaination (Kirk and Karl)

######################################
The pipeline (and certian other operations) will try to Strip an array(or any collection/Ienumerable), so that it can push it down the pipeline one item at a time.. the , just wraps something into an array.. so often if you already have an array you use the , to put that array inside an array , so that when the pipeline strips it, it just pushes the original array down the pipeline as ONE item. look at this
,,,(
1..5)
You will notice the 5 element array is inside a one element array which is inside a one element array which is inside a one element array..
 
now run each of these
,,,(
1..5) | % { $_ }
,,,(1..5) | % { $_ } | % { $_ }
,,,(1..5) | % { $_ } | % { $_ } | % { $_ }
 
you'll see that the "container arrays" get strip at each pipeline level, with the Last line, having been run through a pipeline boundary 3 times, you get the final container array stripped, and the pipeline gets the the items stripped and pushed down one at a time..

Author

Commented:
Excellent answer.  Points increased.

I added a comma in front of the brackets that enclose the array I want to add, and the array now gets added as a single entitiy, just as K & K explained.

Thanks.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.