powershelldictionaryarraylist

Trying (and failing) to define a Dictionary which uses Tuples for Keys, and ArrayLists for Values


I've tried using the following code to set up a new Dictionary in my Powershell code. I want the Dictionary to use a tuple as the key, and an Arraylist as the value (so that I can add items to the value over time).

# Create dictionary
$mydict = [Collections.Generic.Dictionary[[Tuple[int,int]],Collections.ArrayList]]::new()
# Add an empty Arraylist to a key
$mydict.Add([Tuple]::Create(0,0),[Collections.ArrayList]::new())
# Try to add an item to this new arraylist
$mydict[(0,0)].Add(1)
MethodInvocationException: Exception calling "Add" with "1" argument(s): "Collection was of a fixed size."
# And sure enough:
$mydict[(0,0)].IsFixedSize
True
$mydict[(0,0)].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Anyone know why Powershell is ignoring my requests to add ArrayLists as members, and for some reason silently converting the objects to System.Array instead?


Solution

  • Just like you used [Tuple]::Create(0,0), i.e explicit creation of a tuple in the .Add() call, you must use the same in trying to access an entry:

    $null = $mydict[[Tuple]::Create(0,0)].Add(1)
    

    The reason that (0,0) didn't work as a lookup key is that it is of type [object[]] and PowerShell's index operator ([…]) by design supports passing an array of indices, whose elements are individually interpreted as indices to look up.


    [1] Note that PowerShell generally treats objects that implement the System.Collections.IDictionary interface as single objects (scalars) in its pipeline, even though they are enumerable, namely as key-value pairs. However, with a key type that is an implementation of System.Collections.ICollection other than an array, such as System.Tuple`2 in your case, numeric indices, which on their own do not match such a key type, seemingly treat the dictionary instance like a single-element array when intrinsic indexing is applied, so that even multiple indices can be applied, and each index with value 0 or -1 (to select the one and only "element" from the start or the end) returns the dictionary itself.