我使用自定义对象从一组SQL Server对象的保存名称和模式。我把对象到一个数组,然后我得到的一组物体并把那些到另一个阵列。我想现在要做的是找到两个阵列之间的所有精确匹配。

我目前使用这样的:

$filteredSQLObjects = @()

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

有没有更好/更快/更清洁的方式做到这一点?最初的时候我只是用字符串数组工作,我可以只通过第二阵列和使用-contains的一个循环,但似乎并不可能的对象。

谢谢!

有帮助吗?

解决方案

我认为它的更好,如果你定义自定义对象在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
        }
    }
}

修改

OK,一开始,你不能因为它已经在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

其他提示

您可以凝聚这一个班轮如果你在控制台上写这这将是适当的:

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

但是,在一个剧本,我将扩大它就像你拥有了它。它是更易读的方式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top