Search code examples
powershellhashtable

Merging hashtables in PowerShell: how?


I am trying to merge two hashtables, overwriting key-value pairs in the first if the same key exists in the second.

To do this I wrote this function which first removes all key-value pairs in the first hastable if the same key exists in the second hashtable.

When I type this into PowerShell line by line it works. But when I run the entire function, PowerShell asks me to provide (what it considers) missing parameters to foreach-object.

function mergehashtables($htold, $htnew)
{
    $htold.getenumerator() | foreach-object
    {
        $key = $_.key
        if ($htnew.containskey($key))
        {
            $htold.remove($key)
        }
    }
    $htnew = $htold + $htnew
    return $htnew
}

Output:

PS C:\> mergehashtables $ht $ht2

cmdlet ForEach-Object at command pipeline position 1
Supply values for the following parameters:
Process[0]:

$ht and $ht2 are hashtables containing two key-value pairs each, one of them with the key "name" in both hashtables.

What am I doing wrong?


Solution

  • I see two problems:

    1. The open brace should be on the same line as Foreach-object
    2. You shouldn't modify a collection while enumerating through a collection

    The example below illustrates how to fix both issues:

    function mergehashtables($htold, $htnew)
    {
        $keys = $htold.getenumerator() | foreach-object {$_.key}
        $keys | foreach-object {
            $key = $_
            if ($htnew.containskey($key))
            {
                $htold.remove($key)
            }
        }
        $htnew = $htold + $htnew
        return $htnew
    }