In Union and Intersection in PowerShell? cool one-liners for set operations of arrays are described.
I want to do this with hashtables and have a solution using the keysets of the dictionaries. To extend then to the values, I use for-loops to iterate over the intersection of the keys and copy the values over to new result-hashtables. This looks not clean.
Further research showed solutions with GetEnumerator which is also not clean IMHO.
How can I replace the bloated for loops or enumerators by concise and nice one-liners?
Source code below:
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 $_)}
# I don't 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 $_}
You can use the same technique as for lists, but use the hash table keys, as you indicate in the OP.
For union and intersection you have an additional problem. Of the keys in common between the two hash tables, which value will you keep? Assume you will always keep the value in the first hash table. Then:
# 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[$_]}
Or you could do this which avoids the clone and creates a new hash table
# intersection
$newHash = @{}; $hash1.keys | ? {$_ -in $hash2.keys} | % {$newHash[$_] = $hash1[$_]}
# difference: $hash1 - $hash2
$newHash = @{}; $hash1.keys | ? {$_ -notin $hash2.keys} | % {$newHash[$_] = $hash1[$_]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With