Finding matches in object arrays in Powershell

I use custom objects to store the name and schema from a set of SQL Server objects. I put the objects in an array, then get a different set of objects and put them in another array. Now I would like to find all exact matches between the two arrays.

I am currently using this:

$filteredSQLObjects = @()

foreach ($SQLObject1 in $SQLObjects1)
{
    foreach ($SQLObject2 in $SQLObjects2)
    {
        if ($SQLObject1.Name   -eq $SQLObject2.Name -and
            $SQLObject1.Schema -eq $SQLObject2.Schema)
        {
            $filteredSQLObjects += $SQLObject1
        }
    }
}

Is there a better / faster / cleaner way to do this? Initially, when I was just working with arrays of strings, I could just skip one of the arrays and use the -containers on the second, but with objects that don't seem possible.

Thank!

+3
source share
2 answers

, , IsEqualTo . - :

$myObject = New-Object PSObject
$myObject | Add-Member -MemberType NoteProperty -Name Name -Value $name
$myObject | Add-Member -MemberType NoteProperty -Name Schema -Value $schema
$myObject | Add-Member -MemberType ScriptMethod -Name IsEqualTo -Value {
    param (
        [PSObject]$Object
    )

    return (($this.Name -eq $Object.Name) -and ($this.Schema -eq $Object.Schema))
}

, , foreach. :

$filteredSQLObjects = $SQLObjects1 | Where-Object { $SQLObject1 = $_; $SQLObjects2 | Where-Object { $_.IsEqualTo($SQLOBject1) } }

foreach ($SQLObject1 in $SQLObjects1)
{
    foreach ($SQLObject2 in $SQLObjects2)
    {
        if ($SQLObject1.IsEqualTo($SQLObject2))
        {
            $filteredSQLObjects += $SQLObject1
        }
    }
}

, Equals, System.Object (doh!). , IsEqualTo .

, Intersect-Object ( .NET Enumerable.Intersect), (, ). , (, , Sequence, IsEqualTo, $filteredSequence ..), , .

function Intersect-Object
{
    param (
        [Parameter(ValueFromPipeline = $true)]
        [PSObject]$Object,
        [Parameter(Mandatory = $true)]
        [PSObject[]]$Sequence
    )

    begin
    {
        $filteredSequence = @()
    }

    process
    {
        $Sequence | Where-Object { $_.IsEqualTo($Object) } | ForEach-Object { $filteredSequence += $_ }
    }

    end
    {
        return $filteredSequence
    }
}

foreach :

$filteredSQLObjects = $SQLObjects1 | Intersect-Object -Sequence $SQLObjects2
+2

, , :

$filtered = $SQLObjects1 | ? {$o1=$_; $SQLObjects2 | ? {$_.Name -eq $o1.Schema `
                                                   -and $_.Name -eq $o1.Schema}}

script , . .

+2
source

Source: https://habr.com/ru/post/1758027/


All Articles