我認爲它更好,如果您在自定義對象的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,一開始,你不能因爲它已經在System.Object
存在添加Equals
成員(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
這並沒有擺脫雙循環,但它更乾淨。謝謝!將問題打開一段時間,以查看是否有其他解決方案。 – 2010-08-04 16:27:09
您可以添加一個Equals。您只需使用-force開關覆蓋現有的方法。我發現了這一點,因爲這就是我所做的:) – 2010-08-04 21:09:47