Sometimes I write something—as in some PowerShell—and I feel like, while I don’t need it right now and here today, I should put it somewhere. I just found a screenshot where I did that. Maybe it’ll help someone, and posting it here on my site will likely allow me to find it when I’ll need it, versus looking around on random computers for random screenshots. I would’ve never found this image were I actually looking for it.
I must’ve wondered, can I embed both a hash table and an array in a hashtable? I can. First, however, let’s start with a single, simple array, and a single simple hashtable. Let’s make sure we know these.
An array is a collection—remember that word, as you’ll hear it again in PowerShell (in place of “array”)—of items. In other languages, you might hear it referred to as a list. That’s not a bad visual. I write what I need at the grocery store on a Post-it note. I suppose it’s an array; it is a collection of items that I need at home, whether it be food, cleaning supplies, or something else. In the next example, we’ll create two identical arrays in two different manners—one without and one with the array sub-expression operator—and store them in two separate variables.
$ArrayWithoutOperator = 'e','f','g' $ArrayWithOperator = @('e','f','g') $ArrayWithoutOperator
e f g
$ArrayWithOperator
e f g
Let’s prove that at least one of these is an array. While I practically never use Format-Table
, I’ve used it in this example to ensure all the output is packed as closely as possible to the left.
ArrayWithoutOperator.GetType() | Format-Table -AutoSize
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
It is!
A hash table—and this is my favorite way in which to explain it—is an associative array. Huh? It’s still an array or a list, but now, each item has an association. Each item in the array contains a key and a value. Take a look, keeping in mind that PowerShell will label the keys with “Name” (while the value will be labeled with “Value”).
$Hashtable = @{'mid1' = 'c';'mid2' = 'd'} $Hashtable
Name Value ---- ----- mid2 d mid1 c
Now, let’s recreate our array and our hash table inside of another hash table. I’m going to show this using both a single line and multiple lines. It’s important to see those semicolons.
@{'top1' = 'a';'top2' = 'b';'top3' = @{'mid1' = 'c';'mid2' = 'd'}; 'bottom1' = @('e','f','g')} @{ 'top1' = 'a' 'top2' = 'b' 'top3' = @{'mid1' = 'c';'mid2' = 'd'} 'bottom1' = @('e','f','g') }
Name Value ---- ----- top2 b bottom1 {e, f, g} top3 {[mid2, d], [mid1, c]} top1 a
That output is painful. As you may have been able to guess, based on the values, I wanted to see elements labeled using “top” at the top of this list, and the element using “bottom” at the bottom. This is how hash tables work in PowerShell in my experience: You’re not going to get it back the way you might expect. Therefore, you’re going to need to know about the ordered attribute which you can apply to a hash table to create an ordered dictionary.
[ordered]@{ 'top1' = 'a' 'top2' = 'b' 'top3' = @{'mid1' = 'c';'mid2' = 'd'} 'bottom1' = @('e','f','g') }
Name Value ---- ----- top1 a top2 b top3 {[mid2, d], [mid1, c]} bottom1 {e, f, g}
Now that we have it in the order in which we expect, let’s pay a bit more attention to the associated values for each key. The key top3
is our embedded, or nested, hash table. We can see the representation in the value, where the nested keys and associated value are displayed as [mid2, d]
, [mid1, c]
indicating a hash table (or associative array). Our value for the bottom1
key is e
, f
, g
, indicating an array. And as easy as that, a hash table can be a container for additional hash tables and arrays.