Search code examples
arrayspowershellmultidimensional-arrayiterationhashtable

Powershell Compare 2 Arrays of Hashtables based on a property value


I have one array of hashtables like the one below:

$hashtable1 = @{}
$hashtable1.name = "aaa"
$hashtable1.surname =@()
$hashtable1.surname += "bbb"

$hashtable2 = @{}
$hashtable2.name = "aaa"
$hashtable2.surname =@()
$hashtable2.surname += "ccc"

$hashtable3 = @{}
$hashtable3.name = "bbb"
$hashtable3.surname = @()
$hashtable3.surname += "xxx"
$A = @($hashtable1; $hashtable2; $hashtable3)

I need to iterate though the array and I need to find out duplicates based on hashtable[].name

Then I need to group those hashtable.surname to hashtable[].surname so that the result will be an array of hashtables that will group all for name all the surnames:


$hashtable1.name = "aaa"
$hashtable1.surname = ("bbb","ccc")

$hashtable3.name = "bbb"
$hashtable3.surname = ("xxx")

I was looking into iterating to empty array

+

I have found this link:

powershell compare 2 arrays output if match

but I am not sure on how to reach into the elements of the hashtable.

My options:

  1. I was wondering if -contain can do it.
  2. I have read about compare-object but I am not sure it can be done like that. (It looks a bit scary in the moment)

I am on PS5.

Thanks for your help, Aster


Solution

  • You can group your array items by the names using a scriptblock like so. Once grouped, you can easily build your output to do what you seek.

    #In PS 7.0+ you can use Name directly but earlier version requires the use of the scriptblock when dealing with arrays of hashtables.
    $Output = $A | Group-Object -Property {$_.Name} | % {
        [PSCustomObject]@{
            Name = $_.Name
            Surname = $_.Group.Surname | Sort-Object -Unique
        }
    }
    

    Here is the output variable content.

    Name Surname
    ---- -------
    aaa  {bbb, ccc}
    bbb  xxx
    

    Note Improvements have been made in PS 7.0 that allows you to use simply the property name (eg: Name) in Group-Object for arrays of hashtables, just like you would do for any other arrays type. For earlier version though, these particular arrays must be accessed by passing the property in a scriptblock, like so: {$_.Name}

    References

    MSDN - Group_Object

    SS64 - Group Object

    Dr Scripto - Use a Script block to create custom groupings in PowerShell