我认为如果您在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))
}
然后你可以像 Keith 向我们展示的那样做一个单行,或者只是做你的双重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