Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

compare an array of hashes

by Anonymous Monk
on Mar 09, 2006 at 16:13 UTC ( [id://535422]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have two array of hashes. I'd like to compare the two arrays and decipher based on a particular hash key in each of the hashes
1) The common keys between the arrays
2) If one array contains hash key that is not present in the other array
The hashes (there may be two or more) in each of the arrays are the same structure
e.g.
@array1 = { { hour => "1", minute => "30", flag => "cmd1" }, { hour => "1", minute => "30", flag => "cmd2" }, { hour => "1", minute => "30", flag => "cmd3" } }; @array2 = { { hour => "1", minute => "30", flag => "cmd1" }, { hour => "1", minute => "30", flag => "cmd2" }, { hour => "1", minute => "30", flag => "cmd3" }, { hour => "1", minute => "30", flag => "cmd4" } };
In this example if I wished to use the flag key for comparison purposes between the arrays. How do I do this ?
i.e. flag => "cmd4" only exists in @array2
This is a scaled down version of a real issue I have. Any help appreciated.

Replies are listed 'Best First'.
Re: compare an array of hashes
by inman (Curate) on Mar 09, 2006 at 16:38 UTC
    Functions such as each_array and pairwise from List::MoreUtils will allow you to iterate over two lists at a time and process them. This assumes that your lists are similar and you are just trying to get different items.

    If your data is key driven then you can use a hash to find the unique keys and then grep them from the list.

    my @wanted; my %keys; $keys{$_->{flag}}++ foreach (@array1, @array2); my @unique = grep {$keys{$_->{flag}} == 1} @array2; print Dumper(@unique);
      This is exactly what I was looking for. How do I get a list of the keys that are common to both ?
Re: compare an array of hashes
by leocharre (Priest) on Mar 09, 2006 at 16:58 UTC

    I'm going to solve the problem by creating a rudimentary "digest" of each anonymous hash in each array. Hash %structures will hold the "digests" as keys to anonymous arrays that will hold where the "digest" came from, what array, and what position.

    This will be ugly- the output will be mainly for you- it wouldn't be so useful for code, I suppose- but I really have no idea what you expect as output- it's too vague.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my @array1 = ( { hour => "1", minute => "30", flag => "cmd1" }, { hour => "1", minute => "30", flag => "cmd2" }, { hour => "1", minute => "30", flag => "cmd3" } ); my @array2 = ( { hour => "1", minute => "30", flag => "cmd1" }, { hour => "1", minute => "30", flag => "cmd2" }, { hour => "1", minute => "30", flag => "cmd3" }, { iamdifferent =>'because', hour => "1", minute => "30", flag => "cmd4" }, { iamdifferent =>'because', hour => "1", minute => "40", flag => "cmd6" }, { iamdifferent =>'because', hour => "1", minute => "40", flag => "cmd6", minute => "40" }, { a =>'because', b => "1", c => "40", d => "cmd6", minute => "40" } ); # this will hold my hash "digests" as keys to lists of # what array and position it happened in. my %structures=(); # the arrays with anon hashes we will analize my @arrays=(\@array1, \@array2); my $which_array=0; for (@arrays){ my $a=$_; my $anon_hash_position_in_array=0; for (@{$a}){ my $structure; for my $k(sort (keys %{$_})){ $structure.=":$k:"; } my $val= "array$which_array"."_position$anon_hash_position_in_ +array"; push @{$structures{$structure}}, $val; $anon_hash_position_in_array++; } $which_array++; } print Dumper(\%structures); exit;

    Output:

    $VAR1 = { ':flag::hour::minute:' => [ 'array0_position0', 'array0_position1', 'array0_position2', 'array1_position0', 'array1_position1', 'array1_position2' ], ':flag::hour::iamdifferent::minute:' => [ 'array1_position3' +, 'array1_position4' +, 'array1_position5' ], ':a::b::c::d::minute:' => [ 'array1_position6' ] };
Re: compare an array of hashes
by ayrnieu (Beadle) on Mar 09, 2006 at 17:37 UTC
    The quickest solution would make use of accelerated, unsorted invocations of List::Compare

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://535422]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-20 01:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found