How to specify data type for hashtable?

10.8k views Asked by At

It seems PowerShell hashtable (@{}) is map of string→string by default. But I wish that my value type is Int32 so that I could do calculation on it.

How could I specify the type information when declaring a hashtable variable?

2

There are 2 answers

0
Ansgar Wiechers On BEST ANSWER

Hashtables map keys to values. The type of the keys and values is immaterial.

PS C:\> $ht = @{}
PS C:\> $ht[1] = 'foo'
PS C:\> $ht['2'] = 42
PS C:\> $ht

Name                           Value
----                           -----
2                              42
1                              foo

PS C:\> $fmt = "{0} [{1}]`t-> {2} [{3}]"
PS C:\> $ht.Keys | % {$fmt -f $_, $_.GetType().Name, $ht[$_], $ht[$_].GetType().Name}
2 [String]      -> 42 [Int32]
1 [Int32]       -> foo [String]

If you have an integer in a string and want to assign that as an integer, you can simply cast it on assignment:

PS C:\> $ht[3] = [int]'23'
PS C:\> $ht.Keys | % {$fmt -f $_, $_.GetType().Name, $ht[$_], $ht[$_].GetType().Name}
2 [String]      -> 42 [Int32]
3 [Int32]       -> 23 [Int32]
1 [Int32]       -> foo [String]
0
zett42 On

An alternative to Hashtable is the Dictionary which allows to explicitly specify type of key and value.

In the following, a dictionary with string key and int value will be created:

[Collections.Generic.Dictionary[string, int]] $dict = @{}
    
$dict['a'] = 42      # Ok
$dict['b'] = '42'    # Ok (implicit type conversion)
$dict['c'] = 'abc'   # Error: Cannot convert value "abc" to type "System.Int32"

Note that a Dictionary created this way has case-sensitive keys, contrary to a Hashtable, whose keys are case-insensitive.

$dict['a'] = 42
$dict['A'] = 21  # Creates a 2nd entry!

To make the Dictionary case-insensitive like a Hashtable, it must be created differently, by passing a StringComparer to the Dictionary constructor:

$dict = [Collections.Generic.Dictionary[string, int]]::new( [StringComparer]::InvariantCultureIgnoreCase )
$dict['a'] = 42
$dict['A'] = 21  # Overwrites the entry whose key is 'a'