Jigar Solanki
Jigar Solanki

Reputation: 91

How to compare Associative arrays in Powershell?

I have two associative arrays

$a = @{"k1"="v1"; "k2"=@{"k21"="v21"}} 

$b = @{"k1"="v1"; "k2"=@{"k21"="v21"}} 

I was wondering is there any good way do the comparison without writing my own function?

Upvotes: 7

Views: 2678

Answers (2)

Emperor XLII
Emperor XLII

Reputation: 13452

Just for completeness, here is a simple function for comparing hashtables:

function Compare-Hashtable(
  [Hashtable]$ReferenceObject,
  [Hashtable]$DifferenceObject,
  [switch]$IncludeEqual
) {
  # Creates a result object.
  function result( [string]$side ) {
    New-Object PSObject -Property @{
      'InputPath'= "$path$key";
      'SideIndicator' = $side;
      'ReferenceValue' = $refValue;
      'DifferenceValue' = $difValue;
    }
  }

  # Recursively compares two hashtables.
  function core( [string]$path, [Hashtable]$ref, [Hashtable]$dif ) {
    # Hold on to keys from the other object that are not in the reference.
    $nonrefKeys = New-Object 'System.Collections.Generic.HashSet[string]'
    $dif.Keys | foreach { [void]$nonrefKeys.Add( $_ ) }

    # Test each key in the reference with that in the other object.
    foreach( $key in $ref.Keys ) {
      [void]$nonrefKeys.Remove( $key )
      $refValue = $ref.$key
      $difValue = $dif.$key

      if( -not $dif.ContainsKey( $key ) ) {
        result '<='
      }
      elseif( $refValue -is [hashtable] -and $difValue -is [hashtable] ) {
        core "$path$key." $refValue $difValue
      }
      elseif( $refValue -ne $difValue ) {
        result '<>'
      }
      elseif( $IncludeEqual ) {
        result '=='
      }
    }

    # Show all keys in the other object not in the reference.
    $refValue = $null
    foreach( $key in $nonrefKeys ) {
      $difValue = $dif.$key
      result '=>'
    }
  }

  core '' $ReferenceObject $DifferenceObject
}

Some example output:

> $a = @{ 'same'='x'; 'shared'=@{ 'same'='x'; 'different'='unlike'; 'new'='A' } }
> $b = @{ 'same'='x'; 'shared'=@{ 'same'='x'; 'different'='contrary' }; 'new'='B' }
> Compare-Hashtable $a $b

InputPath          ReferenceValue   DifferenceValue   SideIndicator
---------         --------------   ---------------   -------------
shared.different   unlike           contrary          <>
shared.new         A                                 <=
new                                 B                =>

Upvotes: 3

Keith Hill
Keith Hill

Reputation: 201922

There isn't a way that I know of except writing a function to compare each key's value (potentially recursive if the value is something other than a primitive object). However, associate arrays in PowerShell are just .NET types (System.Collections.Hashtable). You might want to open this question up to the broader .NET audience by adding the .NET tag to your question.

Upvotes: 4

Related Questions