Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access values in an ordered PowerShell hash table using integer keys?

My requirement is to store integer keys and access hash table values using those integer keys in an ordered hash table.

What works

When I use string keys, no problem:

cls

$foo=[ordered]@{}

$foo.add("12",1)
$foo.add("24",2)

write-host ("first item=" + $foo.Item("12"))
write-host ("second item=" + $foo.Item("24"))

Output:

first item=1
second item=2

Using Brackets Fails

When I use brackets, the program doesn't throw an exception, but it returns nothing:

$fooInt=[ordered]@{}

$fooInt.add(12,1)
$fooInt.add(24,2)

write-host ("first item=" + $fooInt[12])
write-host ("second item=" + $fooInt[24])

Output:

first item=
second item=

Using the Item method Fails

When I use the Item method and integer keys, PowerShell interprets the integer key as an index and not a key:

$fooInt=[ordered]@{}

$fooInt.add(12,1)
$fooInt.add(24,2)

write-host ("first item=" + $fooInt.Item(12))
write-host ("second item=" + $fooInt.Item(24))

Output:

Exception getting "Item": "Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"
At line:8 char:1
+ write-host ("first item=" + $fooInt.Item(12))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], GetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenGetting

Exception getting "Item": "Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index"
At line:9 char:1
+ write-host ("second item=" + $fooInt.Item(24))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [],  GetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenGetting

How do I access values in a PowerShell hashtable using an integer key?

like image 923
VA systems engineer Avatar asked Jan 28 '23 15:01

VA systems engineer


1 Answers

They keys in a hashtable are objects, not strings. When you're attempting to access the key "12" with the integer 12, it cannot find that entry because the keys don't match.

HOWEVER, you're not using a standard hashtable, you're using an ordered hashtable which has a different Item method on it since it can work by key or index. If you want to access the integer key with an ordered hashtable, you need to use a different syntax:

$hash.12

If you use the array accessor syntax:

$hash[12]

it will try to return the 13th item in the list.


You can observe the difference between these objects by using Get-Member:

$orderedHash | Get-Member Item

   TypeName: System.Collections.Specialized.OrderedDictionary

Name MemberType            Definition
---- ----------            ----------
Item ParameterizedProperty System.Object Item(int index) {get;set;}, System.Object Item(System.Object key) {get;set;}

$hash | Get-Member Item

   TypeName: System.Collections.Hashtable

Name MemberType            Definition
---- ----------            ----------
Item ParameterizedProperty System.Object Item(System.Object key) {get;set;}

After some more experimentation, this is only the case on the int32 type. If you define and access it with a different type, it will work since it's no longer matching the overloaded int signature:

$hash = [ordered]@{
    ([uint32]12) = 24
}
$hash[[uint32]12]
> 24
like image 58
Maximilian Burszley Avatar answered Mar 05 '23 18:03

Maximilian Burszley