Powershell 5,是否有一种简单的方法来比较哈希表数组中的 属性 值

Powershell 5, Is there an easy way to compare property values from array of hashtables

我正在尝试找到一种方法来比较 2 个哈希表数组,看看是否存在某些 属性 的匹配项。

如果要匹配,我需要某个值才能发生,如果没有匹配,则需要执行其他操作。

理论上嵌套循环应该可以完成这项工作,但我必须弄清楚哪个数组更长。

代码示例为:

$hashtable1 = @{}
$hashtable1.name = "xxx"
$hashtable1.surname =@()
$hashtable1.surname += "bbb"

$hashtable2 = @{}
$hashtable2.name = "aaa"
$hashtable2.surname =@()
$hashtable2.surname += "ccc"

$hashtable3 = @{}
$hashtable3.name = "bbb"
$hashtable3.surname = @()
$hashtable3.surname += "xxx"

$A = @($hashtable1; $hashtable2; $hashtable3)

$hashtable4 = @{}
$hashtable4.name = "yyy"
$hashtable4.surname =@()
$hashtable4.surname += "bbb"

$hashtable5 = @{}
$hashtable5.name = "xxx"
$hashtable5.surname = @()
$hashtable5.surname += "ccc"

$hashtable6 = @{}
$hashtable6.name = "ddd"
$hashtable6.surname = @()
$hashtable6.surname += "xxx"

$hashtable7 = @{}
$hashtable7.name = "ddd"
$hashtable7.surname = @()
$hashtable7.surname += "xxx"

$Array1 = @($hashtable1; $hashtable2; $hashtable3)
$Array2 = @($hashtable4; $hashtable5; $hashtable6; $hashtable7)

在这种情况下,我需要找出:hashtable1.name与hashtable5.name相同,然后采取一定的行动。

我在想有没有更好的办法

请注意,我昨天在这里问了一个类似的问题:

该解决方案适用于有点不同的场景,但这次,我真的需要比较数组中哈希表的参数。

我在 windows10.

上使用 PowerShell 5

谢谢, 紫苑

您可以测试:

$commonNames = (Compare-Object $Array1.name $Array2.name -IncludeEqual -ExcludeDifferent).inputObject

除了。我认为 return 匹配的对象可能有用。如果您展开名字 属性,那么只有名字 属性 会被 return 编辑。幸运的是 Compare-Object 有一些参数可以帮助解决这个问题。特别是:

-Property : 指示 Compare-Object 要比较的基础对象 属性。

-PassThru : Returns 添加了 属性 "SideIndicator" 的原始对象此时您仍然可以确定哪些对象具有等效的名称属性。

这可能最终看起来像:

Compare-Object $Array1 $Array2 -Property Name -PassThru -IncludeEqual | 
Where-Object{ $_.SideIndicator -eq '==' }

但是:

这不会很好地过滤,因为根据定义哈希表是集合 Name/Value 对,因此当 PowerShell 展开数组进行比较时,它会尝试过滤 [=42= 中的名称 column/property ] 对,这不是你想要的。相反,您想过滤名称键的值被“名称”引用,这非常令人困惑。您可以通过将散列 table 正式转换为对象来解决这个问题,PowerShell 使这变得非常简单:

$Array1 = @([PSCustomObject]$hashtable1; [PSCustomObject]$hashtable2; [PSCustomObject]$hashtable3)
$Array2 = @([PSCustomObject]$hashtable4; [PSCustomObject]$hashtable5; [PSCustomObject]$hashtable6; [PSCustomObject]$hashtable7)

Compare-Object $Array1 $Array2 -Property Name -PassThru -IncludeEqual | 
Where-Object{ $_.SideIndicator -eq '==' }

现在如果这是 suitable 你可以稍微清理一下:

$Object1 = [PSCustomObject]@{
    $Object1.name    = "xxx"
    $Object1.surname = @("bbb")
}

$Object2 = [PSCustomObject]@{
    $Object2.name    = "aaa"
    $Object2.surname = @("ccc")
}

$Object3 = [PSCustomObject]@{
    $Object3.name    = "bbb"
    $Object3.surname =  @("xxx")
}

$Object4 = [PSCustomObject]@{
    $Object4.name    = "yyy"
    $Object4.surname = @("bbb")
}

$Object5 = [PSCustomObject]@{
    $Object5.name    = "xxx"
    $Object5.surname =  @("ccc")
}

$Object6 = [PSCustomObject]@{
    $Object6.name    = "ddd"
    $Object6.surname =  @("xxx")
}

$Object7 = [PSCustomObject]@{
    $Object7.name    = "ddd"
    $Object7.surname =  @("xxx")
}

$Array1 = @($Object1; $Object2; $Object3)
$Array2 = @($Object4; $Object5; $Object6; $Object7)

Compare-Object $Array1 $Array2 -Property Name -PassThru -IncludeEqual | 
Where-Object{ $_.SideIndicator -eq '==' }

上面的示例只是说您不妨从对象开始,像以前一样,可以通过简单地将散列 table 转换为 [PSCustomObject] 来创建对象。但是,在这种情况下,我们将转换 Hash 文字而不是变量。请注意,您不需要使用 += 来附加姓氏值。

注意:我知道您提供的散列table可能只是一个简单的演示构造。如果输入真的来自其他地方,我们可能不得不编写一些不同的代码以遵循概念上的相同模式。

您还可以 return 哈希表本身匹配,而不仅仅是 .name 属性 像这样:

Compare-Object $Array1 $Array2 -IncludeEqual -ExcludeDifferent -Property @{Expression = {$_['name']}} -PassThru

-Property参数的值可以是新计算的属性.
通过使用 -PassThru 参数,Compare-Object 省略了比较对象周围的 PSCustomObject 包装器,并且 returns 不同或相等的对象,不变。

结果:

Name                           Value                                                                                                                                     
----                           -----                                                                                                                                     
name                           xxx                                                                                                                                       
surname                        {bbb}

P.S。使用

创建可以简化的数组
$Array1 = $hashtable1, $hashtable2, $hashtable3
$Array2 = $hashtable4, $hashtable5, $hashtable6, $hashtable7

所以你不需要 @()