Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 465
Jigar Solanki Avatar asked Dec 23 '10 19:12

Jigar Solanki


2 Answers

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.

like image 175
Keith Hill Avatar answered Sep 21 '22 12:09

Keith Hill


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                =>
like image 22
Emperor XLII Avatar answered Sep 19 '22 12:09

Emperor XLII