Given an ordered dictionary, I would like to get the key at index 0. I can of course do a loop, get the key of the first iteration and immediately break out of the loop. But I wonder if there is a way to do this directly? My Google-Fu has not turned up anything, and some shots in the dark have failed too. I have tried things like
$hash[0].Name
and
$hash.GetEnumerator()[0].Name
I found this discussion about doing it in C#, which lead to this
[System.Collections.DictionaryEntry]$test.Item(0).Key
but that fails too. Is this just something that can't be done, or am I going down the wrong path?
Use the .Keys
collection:
$orderedHash = [ordered] @{ foo = 1; bar = 2 }
# Note the use of @(...)
@($orderedHash.Keys)[0] # -> 'foo'
Note:
Use of @(...)
, the array-subexpression operator, enumerates the .Keys
collection and collects its elements in an [object[]]
array, which enables access by positional indices.
The .Keys
collection itself implements only the System.Collections.ICollection
interface, which supports enumeration, but not indexed access.
@(...)
to enable indexing will no longer be necessary in PowerShell (Core) 7.3+ (.NET 7+), thanks to an improvement initiated by iRon via GitHub issue #56835: The .Keys
collection will then implement the System.Collections.IList
interface, which does support positional indexing. Note that this change will only apply to ordered hashtables ([ordered] @{ ... }
, System.Collections.Specialized.OrderedDictionary
), not also to regular (unordered) hashtables (@{ ... }
) or other types implementing the System.Collections.IDictionary
interface. However, iRon has created a follow-up proposal to make the .Keys
property indexable for all (definition-)ordered and sorted dictionaries - see GitHub issue #63537.
.Name
is an alias property provided by PowerShell; the type-native property containing each System.Collections.DictionaryEntry
's key is .Key