在Union and Intersection in Powershell?冷却单行中描述了数组的设置操作。
我想用哈希表做这个,并使用字典的键集来解决。为了扩展到值,我使用for循环迭代密钥的交集并将值复制到新的结果哈希表。这看起来不干净。
进一步研究显示GetEnumerator的解决方案也不干净恕我直言。
如何通过简洁明了的单行替换膨胀的for循环或枚举器?
以下源代码:
http://paste.ubuntu.com/13362425/
# import csv
$a = Import-Csv -Path A.csv -Delimiter ";" -Header "Keys","Values"
$b = Import-Csv -Path B.csv -Delimiter ";" -Header "Keys","Values"
# make nice hashtables for further use
$AData = @{}
foreach($r in $a)
{ $AData[$r.Keys] = $r.Values }
$BData = @{}
foreach($r in $b)
{ $BData[$r.Keys] = $r.Values }
# set difference to find missing entries
$MissingA = $AData.Keys | ?{-not ($BData.Keys -contains $_)}
# dont know how to do set-operations on hashtables yet. so use keysets and copy data. (lame!)
$MissingAData = @{}
foreach($k in $MissingA)
{
$MissingAData[$k] = $AData[$k]
}
#intersection
$Common = $AData.Keys | ?{$BData.Keys -contains $_}
答案 0 :(得分:5)
您可以使用与列表相同的技术,但使用哈希表键,如您在OP中指出的那样。
对于联合和交叉,您还有一个问题。在两个哈希表之间共同的键,你会保留哪个值?假设您将始终将值保留在第一个哈希表中。然后:
# need clone to prevent .NET exception of changing hash while iterating through it
$h1clone = $hash1.clone()
# intersection
$h1clone.keys | ? {$_ -notin $hash2.keys} | % {$hash1.remove($_)}
# difference: $hash1 - $hash2
$h1clone.keys | ? {$_ -in $hash2.keys} | % {$hash1.remove($_)}
# union. Clone not needed because not iterating $hash1
$hash2.keys | ? {$_ -notin $hash1.keys} | % {$hash1[$_] = $hash2[$_]}
或者你可以这样做,避免克隆并创建一个新的哈希表
# intersection
$newHash = @{}; $hash1.keys | ? {$_ -in $hash2.keys} | % {$newHash[$_] = $hash1[$_]}
# difference: $hash1 - $hash2
$newHash = @{}; $hash1.keys | ? {$_ -notin $hash2.keys} | % {$newHash[$_] = $hash1[$_]}