0

I have two arrays of custom objects - $deploy and $directory. They have 4 properties in common and 1 property that is unique to each. I need to find the members of both arrays where the 4 common properties are the same, but i need to track the 2 unique properties for the matches as well.

Using compare-object on the two arrays with the defined same properties, -passthru and -includeequal is almost it, but only gives me the first (reference) object with its unique property, not the unique property on the difference object.

So I can't simply compare the two arrays and get what I need. I either need to do a nested loop, or hack up/find some sort of "set intersection" function. I'm only going to be dealing with a few dozen members of each array so I'm not too concerned about performance.

What approach would you take? For the simple example below, I would want both the environmentname and deploymentdirectory tracked for all matches.

$deploy
GameBuildVersion    : 68858.zip
OnlineVersion       : 70793.zip
ContentVersion      : 68858.69165-1.zip
ContentBuildVersion : 69165-1.zip
environmentname     : Staging35

$directory
GameBuildVersion    : 68858.zip
OnlineVersion       : 70793.zip
ContentVersion      : 68858.69165-1.zip
ContentBuildVersion : 69165-1.zip
deploymentDirectory : C:\deployer\script\deploy-AB
mfinni
  • 65
  • 1
  • 17
  • take a look at the `full join` section of this ... Merging data in PowerShell – Rambling Cookie Monster — http://ramblingcookiemonster.github.io/Join-Object/ – Lee_Dailey Nov 02 '18 at 17:27
  • Try [`Join-Object`](https://stackoverflow.com/a/45483110/1701026): `$deploy | FullJoin $directory GameBuildVersion, OnlineVersion, ContentVersion, ContentBuildVersion` – iRon Nov 02 '18 at 18:54
  • 1
    @Lee_Dailey - that function only works on a single property per object, I need to have a all-4-match for the *version properties unfortunately. – mfinni Nov 02 '18 at 22:04
  • @mfinni - argh! i thot the `full join` section did as desired. a re-read makes that obviously incorrect. thank you for pointing that out! [*grin*] – Lee_Dailey Nov 02 '18 at 22:34

1 Answers1

2

This may not be the fastest approach, but here's what I've come up with:

# create a string array storing the combined properties of the 4 common $deploy objects.
# convert these strings to lowercase, because later on we use IndexOf and that is case sensitive.
$commons = @()
$deploy | ForEach-Object {
    $commons += $("{0},{1},{2},{3}" -f $_.GameBuildVersion, $_.OnlineVersion, $_.ContentVersion, $_.ContentBuildVersion).ToLower()
}

# create an array to store the objects both arrays have in common, combined with their unique properties
$result = @()
$directory | ForEach-Object {
    $props = $("{0},{1},{2},{3}" -f $_.GameBuildVersion, $_.OnlineVersion, $_.ContentVersion, $_.ContentBuildVersion).ToLower()
    $index = $commons.IndexOf($props)
    if ($index -ge 0) {
        $result += [PSCustomObject]@{
            GameBuildVersion    = $_.GameBuildVersion
            OnlineVersion       = $_.OnlineVersion
            ContentVersion      = $_.ContentVersion
            ContentBuildVersion = $_.ContentBuildVersion        
            deploymentDirectory = $_.deploymentDirectory
            environmentname     = $deploy[$index].environmentname
        }
    }
}

# show the result (or export it to CSV or whatever)
$result

Using the examples you gave, this will yield:

GameBuildVersion    : 68858.zip
OnlineVersion       : 70793.zip
ContentVersion      : 68858.69165-1.zip
ContentBuildVersion : 69165-1.zip
deploymentDirectory : C:\deployer\script\deploy-AB
environmentname     : Staging35
Theo
  • 57,719
  • 8
  • 24
  • 41
  • That's essentially what I ended up doing. Although I just looped through $deploys, and did a Compare-Object with $directory as the reference array, matching on all 4 properties, with passthru to preserve the extra property so I can capture it. – mfinni Nov 05 '18 at 20:34