在 powershell 中,如何在数组中测试已经包含具有所有相同属性的对象?

In powershell, how to test in an array already contains an object with all the same properties?

我想避免在 powershell 中向数组中插入重复项。尝试使用 -notcontains 似乎不适用于 PSCUstomObject 数组。

这是一个代码示例

$x = [PSCustomObject]@{
    foo = 111
    bar = 222
}

$y = [PSCustomObject]@{
    foo = 111
    bar = 222
}

$collection = @()

$collection += $x

if ($collection -notcontains $y){
    $collection += $y
}


$collection.Count #Expecting to only get 1, getting 2

为此我会使用 Compare-Object

$x = [PSCustomObject]@{
    foo = 111
    bar = 222
}

$y = [PSCustomObject]@{
    foo = 111
    bar = 222
}
$collection = [System.Collections.Arraylist]@()

[void]$collection.Add($x)

if (Compare-Object -Ref $collection -Dif $y -Property foo,bar | Where SideIndicator -eq '=>') {
    [void]$collection.Add($y)
}

解释:

使用 comparison operators 将自定义对象与另一个对象进行比较并非易事。此解决方案比较您关心的特定属性(在本例中为 foobar)。这可以简单地使用 Compare-Object 来完成,默认情况下它将输出任一对象的差异。 =>SideIndicator值表示区别在于传递给-Difference参数的对象。

[System.Collections.Arraylist] 类型用于数组以避免在增长数组时通常出现的低效 +=。由于 .Add() 方法会生成正在修改的索引的输出,因此 [void] 转换用于抑制该输出。


您可以对有关属性的解决方案充满活力。您可能不想将 属性 名称硬编码到 Compare-Object 命令中。您可以改为执行以下操作。

$x = [PSCustomObject]@{
    foo = 111
    bar = 222
}

$y = [PSCustomObject]@{
    foo = 111
    bar = 222
}
$collection = [System.Collections.Arraylist]@()

[void]$collection.Add($x)
$properties = $collection[0] | Get-Member -MemberType NoteProperty |
                  Select-Object -Expand Name

if (Compare-Object -Ref $collection -Dif $y -Property $properties | Where SideIndicator -eq '=>') {
    [void]$collection.Add($y)
}