Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if Powershell Array Contains Object of Another Array

I have to arrays in Powershell. Each Array contains an array of objects. These objects have two properties:

Name: String
Id: GUID

The first Array has 4413 objects in it and the second has 4405. The counts are irrelevant, but I only mention them to note that the contents of Array1 and Array2 are different.

Here is my current code (pseudo):

#Fill Array1
$Array1 = Fill-Array1

#Fill Array2
$Array2 = Fill-Array2

#Loop through the arrays and write out the names of all items in Array2 that are different than Array1
ForEach($Val in $Array2)
{
    $Name = $Val.Name

    If($Array1 -notcontains $Val) //this does not work
    {
        Write-Host $Name
    }
}

What is the correct way to check for the existence of the object in Array1? Is my only option to do a nested loop?

Update, using the answer from Manu P below, the following is how I implemented the solution:

#Fill Array1
    $Array1 = Fill-Array1

    #Fill Array2
    $Array2 = Fill-Array2

    #Compare the arrays
    $ComparedResults = Compare-Object -ReferenceObject $Array1 -DifferenceObject $Array2 #I left out the -IncludeEqual param because I don't care about those results

    ForEach($Result in $ComparedResults)
    {
        If($Result.SideIndicator -eq "=>") #the value in Array2 is different than Array1
        {
            $Val = $Result.InputObject

            Write-Host $Val.Name            
        }        
    }
like image 307
crackedcornjimmy Avatar asked Jan 30 '23 19:01

crackedcornjimmy


2 Answers

You can use Compare-Object cmdlet :

Compare-Object -ReferenceObject $Array1 -DifferenceObject $Array2 -IncludeEqual

https://learn.microsoft.com/fr-fr/powershell/module/Microsoft.PowerShell.Utility/Compare-Object?view=powershell-5.0

https://technet.microsoft.com/fr-fr/library/ee156812.aspx

like image 179
Manu Avatar answered Feb 15 '23 18:02

Manu


As GUIDs are comparable you can simply (inner)join the arrays using the function described here: https://stackoverflow.com/a/45483110/1701026

$Array1 = @(
    [pscustomobject]@{Name = "a"; Id = [guid]::NewGuid()}
    [pscustomobject]@{Name = "b"; Id = [guid]::NewGuid()}
    [pscustomobject]@{Name = "c"; Id = [guid]"de5e32c6-5338-4287-8c21-2dd5957cfffe"}
    [pscustomobject]@{Name = "d"; Id = [guid]"345f9ac2-86a0-4b01-b843-5f4bd55f5e21"}
    [pscustomobject]@{Name = "e"; Id = [guid]"953c1442-ed51-445e-a8f5-687120d98f83"}
    [pscustomobject]@{Name = "f"; Id = [guid]::NewGuid()}
)

$Array2 = @(
    [pscustomobject]@{Name = "b"; Id = [guid]::NewGuid()}
    [pscustomobject]@{Name = "c"; Id = [guid]"345f9ac2-86a0-4b01-b843-5f4bd55f5e21"}
    [pscustomobject]@{Name = "d"; Id = [guid]"345f9ac2-86a0-4b01-b843-5f4bd55f5e21"}
    [pscustomobject]@{Name = "e"; Id = [guid]"953c1442-ed51-445e-a8f5-687120d98f83"}
    [pscustomobject]@{Name = "f"; Id = [guid]"953c1442-ed51-445e-a8f5-687120d98f83"}
    [pscustomobject]@{Name = "g"; Id = [guid]::NewGuid()}
)

$Array1 | InnerJoin $Array2 -Using Name,Id | Format-Table

Result:

Id                                   Name
--                                   ----
345f9ac2-86a0-4b01-b843-5f4bd55f5e21 d
953c1442-ed51-445e-a8f5-687120d98f83 e

To get all records with the same name where Id is not equal:

$Array1 | InnerJoin $Array2 -on {$Left.Name -eq $Right.Name -and $Left.Id -ne $Right.Id} -Merge @{Name = {$Left.$_}} | Format-Table

Result:

Id                                                                           Name
--                                                                           ----
{3b175777-e88f-4248-965b-51dec8639fd6, a43d68de-9ed5-4a13-8f8e-61c6cc501458} b
{de5e32c6-5338-4287-8c21-2dd5957cfffe, 345f9ac2-86a0-4b01-b843-5f4bd55f5e21} c
{2a8c4bf7-cf3a-4c3d-b27b-ecb6f4a4fa43, 953c1442-ed51-445e-a8f5-687120d98f83} f
like image 28
iRon Avatar answered Feb 15 '23 17:02

iRon