Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Comparing hash structures?

Status
Not open for further replies.

ericse

Programmer
Apr 19, 2007
32
US
Hello all,

I'm trying to compare hash structures and return the unique values of each hash.

Code:
my $hash1 = { 'add' => { 'val1' => 1,
                         'val2' => 1,
                         'val3' => 1 },
             'remove' => { 'val4' => 0,
                           'val5' => 0,
                           'val6' => 0 }};
my $hash2 = { 'add' => { 'val1' => 1,
                         'val2' => 1,
                         'val3' => 1,
                         'val7' => 1},
             'remove' => { 'val4' => 0,
                           'val5' => 0,
                           'val6' => 0 }};

Now basically, when they're compared, I want a hash structure returned showing me that hash2 has 1 additional 'add' value (in this it being val7). Comparing the two's equality is relatively easy; finding the diff between one or the other is what I'm having trouble with.

I've read that I can use grep do to this, but from my limited experience using Perl's grep, I thought it only worked on arrays. Any help would be much appreciated.

 
Just make a function to recursively search through your primary hash.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$hash1[/blue] = [red]{[/red]
	[red]'[/red][purple]add[/purple][red]'[/red] => [red]{[/red]
		[red]'[/red][purple]val1[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
		[red]'[/red][purple]val2[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
		[red]'[/red][purple]val3[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
	[red]}[/red],
	[red]'[/red][purple]remove[/purple][red]'[/red] => [red]{[/red]
		[red]'[/red][purple]val4[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
		[red]'[/red][purple]val5[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
		[red]'[/red][purple]val6[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
	[red]}[/red],
[red]}[/red][red];[/red]

[black][b]my[/b][/black] [blue]$hash2[/blue] = [red]{[/red]
	[red]'[/red][purple]add[/purple][red]'[/red] => [red]{[/red]
		[red]'[/red][purple]val1[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
		[red]'[/red][purple]val2[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
		[red]'[/red][purple]val3[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
		[red]'[/red][purple]val7[/purple][red]'[/red] => [fuchsia]1[/fuchsia],
	[red]}[/red],
	[red]'[/red][purple]remove[/purple][red]'[/red] => [red]{[/red]
		[red]'[/red][purple]val4[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
		[red]'[/red][purple]val5[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
		[red]'[/red][purple]val6[/purple][red]'[/red] => [fuchsia]0[/fuchsia],
	[red]}[/red],
[red]}[/red][red];[/red]

[black][b]my[/b][/black] [blue]$diff[/blue] = [maroon]hash_diff[/maroon][red]([/red][blue]$hash2[/blue], [blue]$hash1[/blue][red])[/red][red];[/red]

[black][b]use[/b][/black] [green]Data::Dumper[/green][red];[/red]
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [maroon]Dumper[/maroon][red]([/red][blue]$diff[/blue][red])[/red][red];[/red]

[gray][i]# Hash Difference[/i][/gray]
[gray][i]# - Works on perfect matches only, with keys and values.[/i][/gray]
[gray][i]# - Implemented Recursively, but only with hash reference or string[/i][/gray]
[gray][i]#   values[/i][/gray]
[gray][i]# - Does not necessarily clone internal structures[/i][/gray]
[url=http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/url] [maroon]hash_diff[/maroon] [red]{[/red]
	[gray][i]# Per [URL unfurl="true"]http://en.wikipedia.org/wiki/Subtraction[/URL][/i][/gray]
	[gray][i]# c - b = a  =>  are minuend (c) - subtrahend (b) = difference[/i][/gray]
	[black][b]my[/b][/black] [red]([/red][blue]$minuend[/blue], [blue]$subtrahend[/blue][red])[/red] = [blue]@_[/blue][red];[/red]
	
	[black][b]my[/b][/black] [blue]%diff[/blue][red];[/red]
	[olive][b]while[/b][/olive] [red]([/red][black][b]my[/b][/black] [red]([/red][blue]$key[/blue], [blue]$val[/blue][red])[/red] = [url=http://perldoc.perl.org/functions/each.html][black][b]each[/b][/black][/url] [blue]%$minuend[/blue][red])[/red] [red]{[/red]
		[gray][i]# Doesn't exist at all[/i][/gray]
		[olive][b]if[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/exists.html][black][b]exists[/b][/black][/url] [blue]$subtrahend[/blue]->[red]{[/red][blue]$key[/blue][red]}[/red][red])[/red] [red]{[/red]
			[black][b]my[/b][/black] [blue]$subval[/blue] = [blue]$subtrahend[/blue]->[red]{[/red][blue]$key[/blue][red]}[/red][red];[/red]
			[gray][i]# Ref type comparison[/i][/gray]
			[olive][b]if[/b][/olive] [red]([/red][url=http://perldoc.perl.org/functions/ref.html][black][b]ref[/b][/black][/url][red]([/red][blue]$val[/blue][red])[/red] eq [black][b]ref[/b][/black][red]([/red][blue]$subval[/blue][red])[/red][red])[/red] [red]{[/red]
				[gray][i]# Comparison of each type[/i][/gray]
				[olive][b]if[/b][/olive] [red]([/red]! [black][b]ref[/b][/black] [blue]$val[/blue][red])[/red] [red]{[/red]
					[olive][b]next[/b][/olive] [olive][b]if[/b][/olive] [blue]$val[/blue] eq [blue]$subval[/blue][red];[/red]
					
				[red]}[/red] [olive][b]elsif[/b][/olive] [red]([/red][black][b]ref[/b][/black][red]([/red][blue]$val[/blue][red])[/red] eq [red]'[/red][purple]HASH[/purple][red]'[/red][red])[/red] [red]{[/red]
					[blue]$val[/blue] = [maroon]hash_diff[/maroon][red]([/red][blue]$val[/blue], [blue]$subval[/blue][red])[/red][red];[/red]
					[olive][b]next[/b][/olive] [olive][b]if[/b][/olive] ! [url=http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/url] [blue]%$val[/blue][red];[/red]
					
				[red]}[/red] [olive][b]else[/b][/olive] [red]{[/red]
					[url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Invalid ref type at [blue]$key[/blue][/purple][red]"[/red][red];[/red]
				[red]}[/red]
			[red]}[/red]
		[red]}[/red]

		[blue]$diff[/blue][red]{[/red][blue]$key[/blue][red]}[/red] = [blue]$val[/blue][red];[/red]
	[red]}[/red]
	
	[url=http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/url] \[blue]%diff[/blue][red];[/red]
[red]}[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[/ul]
Core (perl 5.8.8) Modules used :
[ul]
[li]Data::Dumper - stringified perl data structures, suitable for both printing and eval[/li]
[/ul]
[/tt]

- Miller
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top