2

If I create a hashtable, and then try to query it by key, it doesn't retrieve them. This is because the keys aren't actually the individual keys, they're instead something called a "KeyCollection". How do I get the actual key?

$states = @{1=2} #This creates the hashtable

$states.keys[0] #This returned 1

$States.get_item($states.keys[0]) # This returned nothing (expected 1)

$States.keys[0].getType() #This returned "KeyCollection" as the Name.

Can someone explain to me why it's "KeyCollection" and not 1, and how to get to the String?

Andrew Ducker
  • 5,308
  • 9
  • 37
  • 48

2 Answers2

3

Then you need to use get_enumerator, like so:

$states = @{"Alaska"="Big"}
$states.GetEnumerator() | ForEach-Object {
    Write-Host "Key: $($_.Key)"
    Write-Host "Value: $($states[$_.Key])"
}
ojk
  • 2,502
  • 15
  • 17
  • No. I specifically need to iterate through the Keys, do some processing on each one to check something, and then use that key to retrieve the value. Additionally, the actual keys are numbers, not strings. Which seems to work even worse. – Andrew Ducker Oct 24 '14 at 16:51
  • Ok, I see. You need to use the get_enumerator method. Check my updated code. – ojk Oct 24 '14 at 16:55
  • or `$states.keys | % {$key = $_; Do other stuff; $item = $states.item($key)}` – Paul Oct 24 '14 at 21:30
  • In the example in the question, the key was referenced by an index, which cannot be done using this method. In order to convert the keys to an array, where indexes can be used, the `KeyCollection` can be cast to an array. For example, for `$states = @{"Alaska"="Big"}`, an array of string keys can be generated using `[string[]]$states`. When the keys are numeric, an integer array can be used, for example, for `$states = @{1=2}`, an array of integer keys would be generated using `[int[]]$states`. In both cases, `$states[0]` would produce the first key in the array that was generated. – Dave F Feb 23 '21 at 06:31
3

I think what is going on is that KeyCollection doesn't have an indexer so PowerShell is interpreting the use of [0] as an attempt to access an item in an array and the KeyCollection is treated as a single item in an array.

You can loop over the keys with ForEach-Object:

$states.Keys | foreach { Write-Host "Key: $_, Value: $($states[$_])" }
Mike Zboray
  • 39,828
  • 3
  • 90
  • 122