Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

comparing hashtable values

Closed Thread
 
Thread Tools Display Modes
Old 05-19-2008   #1 (permalink)
Cookiecutter
Guest


 

comparing hashtable values

I have a hashtable that contains 3 or more keys with their respective values
as an array. What is the simplest or most efficient way of comparing them
and displaying values that are not common to all of them.

For example:
$ht[1] = @(a,c,d,e,g,h)
$ht[2] = @(a,b,c,d,g,h,i,l)
$ht[3] = @(a,d,i,g,h,k)

I want the display to show:
$ht[1] $ht[2] $ht[3]
c b i
e c k
i
l

Even though 'i' and 'c' are in two of the three keys, it's not common to all
so it's displayed as well.

Old 05-19-2008   #2 (permalink)
Cookiecutter
Guest


 

RE: comparing hashtable values

Sorry, the formatting got screwed up. It should be like below:
$ht[1]: c,e
$ht[2]: b,c,i,l
$ht[3]: i,k
Old 05-20-2008   #3 (permalink)
Kiron
Guest


 

Re: comparing hashtable values

You can use the -NotContains operator:

$ht = @{1 = 'a','c','d','e','g','h'
2 = 'a','b','c','d','g','h','i','l'
3 = 'a','d','i','g','h','k'}

$ht_ = @{one = 'a','c','d','e','g','h'
two = 'a','b','c','d','g','h','i','l'}

$diff1 = $ht[1] | ? {$ht[2] -notContains $_ -or $ht[3] -notContains $_}
$diff2 = $ht[2] | ? {$ht[1] -notContains $_ -or $ht[3] -notContains $_}
$diff3 = $ht[3] | ? {$ht[1] -notContains $_ -or $ht[2] -notContains $_}
&{
$ofs = ','
"`$ht[1]: $diff1"
"`$ht[2]: $diff2"
"`$ht[3]: $diff3"
}

# but it can be tedious, unless you do it through a function.
# The one below takes the name of the hashtable's variable so the output
# is as you want. The hashtable must have at least two 'key, value'
# pairs of arrays.

function Get-Uncommon ($var) {
if (!(test-path variable:$var)) {throw "<`$$var> does not exist"}
if ($var -isNot [string]) {throw 'Invalid type, pass the hash''s name'}
$ofs = ','
$ht = gv $var -va
$keys = (gv $var -va).keys | sort
$ht.getEnumerator() | sort | % {$items = @()} {$items += ,$_.value}
$sync = @(,$items | % {$_ | sort count -des})[0].count
if ($items.count -gt 1) {
$i = 0
while ($i -lt $items.count) {
switch -r ($keys[$i].getType().name) {
string {$local:iKey = $var + '.' + $keys[$i++]; break}
int.* {$local:iKey = $var + '[' + $keys[$i++] + ']'; break}
}
"`$${iKey}: $(1..($items.count - 1) | % {
$test = $items[$_]
$items[0] | ? {$test -notContains $_}
} | sort -u)"
$items = $items[1..($items.count - 1) + 0]
}
}
else {throw 'HashTable contains 1 or 0 item'}
}

# pass the hashtable name:
Get-Uncommon ht
Get-Uncommon ht_

--
Kiron
Old 05-20-2008   #4 (permalink)
Kiron
Guest


 

Re: comparing hashtable values

# here's a revised version

function Get-Uncommon ($var) {
if ($var -isNot [string]) {throw 'Invalid type, pass the hash''s name'}
if (!(test-path variable:$var)) {throw "<`$$var> does not exist"}
$ht = gv $var -va
if ($ht -isNot [hashTable]) {throw 'Invalid type, pass a hash''s name'}
$keys = (gv $var -va).keys | sort
$ht.getEnumerator() | sort | % {$items = @()} {$items += ,$_.value}
$ofs = ','
if ($items.count -gt 1) {
$i = 0
while ($i -lt $items.count) {
switch -r ($keys[$i].getType().name) {
^string$ {
switch -r ($keys[$i]) {
'\s|-' {$iKey = $var + '.''' + $keys[$i++] + ''''; break}
default {$iKey = $var + '.' + $keys[$i++]; break}
}
}
'^int\d*$|^double$' {$iKey = $var + '[' + $keys[$i++] + ']'; break}
}
"`$${iKey}: $(1..($items.count - 1) | % {
$test = $items[$_]
$items[0] | ? {$test -notContains $_}
} | sort -u)"
$items = $items[1..($items.count - 1) + 0]
}
}
else {throw 'HashTable contains 1 or 0 item'}
}

$ht = @{1 = 'a','c','d','e','g','h'
2 = 'a','b','c','d','g','h','i','l'
3 = 'a','d','i','g','h','k'}

$ht_ = @{'one 1' = 'a','c','d','e','g','h'
'two-2' = 'a','b','c','d','g','h','i','l'
three = 'a','d','i','g','h','k'}

$ht__ = @{'one uno' = 'a','c','d','e','g','h'}

Get-Uncommon ht
Get-Uncommon ht_
Get-Uncommon ht__

--
Kiron
Old 05-20-2008   #5 (permalink)
Kiron
Guest


 

Re: comparing hashtable values

# oops! The line:
$ht.getEnumerator() | sort | % {$items = @()} {$items += ,$_.value}

# should be:
$ht.getEnumerator() | sort key | % {$items = @()} {$items += ,$_.value}

--
Kiron
Closed Thread

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Comparing two lists KeithK PowerShell 4 07-09-2008 05:27 PM
Export-Csv multiple hashtable values PShelp PowerShell 2 04-10-2008 03:39 PM
Comparing strings - is it a bug? Tibor Soos PowerShell 7 03-13-2008 08:04 PM
sorting on hashtable values Neil Chambers PowerShell 3 04-08-2007 03:49 AM
Assigning new values to a hashtable Marco Shaw PowerShell 7 02-28-2007 10:01 PM








Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50