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
所以你不需要 @()
我正在尝试找到一种方法来比较 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
除了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
所以你不需要 @()