1

Looking to merge two hash tables with nested tables and/or arrays. I found posting Merging hashtables in Powershell: how? which lead me to crated the following function modifying sonjz code found within the post and it works well with non nested objects however when it comes to nested tables and arrays within the parent tables it fails to merge correctly.

how would one go about updating this code to output the merging of hash tables with nested tables an/or arrays if exists?

    Function Merge-HashTables
    {
        [CmdletBinding(ConfirmImpact = 'Low',
                       PositionalBinding = $true)]
        [OutputType([hashtable])]
        param
        (
            [Parameter(Mandatory = $true,
                       Position = 0)]
            [ValidateNotNullOrEmpty()]
            [hashtable]$BaseTable,

            [Parameter(Mandatory = $true,
                       Position = 1)]
            [ValidateNotNullOrEmpty()]
            [hashtable]$NewTable
        )

        Begin
        {
            [hashtable]$Base = $BaseTable.Clone()
        }

        Process
        {
            foreach ($Key in $NewTable.Keys)
            {
                if ($Base.ContainsKey($Key))
                {
                    $Base.Remove($Key)
                }
            }

            Write-Output ($Base + $NewTable)
        }
    }
MeIITek
  • 11
  • 1
  • Can you elaborate on "it fails to merge correctly"? What results does it produce? Are they consistent with the behavior (shallow vs. deep) of the [`Hashtable.Clone` method](https://learn.microsoft.com/dotnet/api/system.collections.hashtable.clone)? – Lance U. Matthews Nov 30 '18 at 06:26

1 Answers1

0

When you have a conflict of keys in your merge, right now you're just discarding one and keeping the other, so if those are in fact two different objects, you'll always lose some information. In the case of those objects themselves being hashtables or arrays, this still holds true of course, so in order to handle this you'll have to decide which types you want special merging logic to handle.

In the case of hashtables, you could recursively call your own function. You're going to need to have a level parameter to limit how far you can recurse and/or handle circular references.

For arrays you can just add them together.

To determine whether an object is of a certain type, use the -is operator.

This will get more complicated when the values are not the same type, like if one of them is a [hashtable] and one of them is a [string]. How do you combine those?

You might additionally want to handle more types of dictionaries and collections for combination, in which case you can use the -is operator with interfaces, like:

if ($NewTable[$Key] -is [System.Collections.IDictionary]) {
    # handle combining dictionaries
}

And similar with ICollection and the like.

If you have a very limited scope to this function and you can make assumptions about what is expected to be in the values you might have an easier time, really depends on your use case(s).

briantist
  • 45,546
  • 6
  • 82
  • 127