Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
No such thing as a small change

Hash of hashes: Check if the element is present in previous hash table

by snape (Pilgrim)
on Apr 03, 2012 at 23:21 UTC ( #963332=perlquestion: print w/ replies, xml ) Need Help??
snape has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monk

I have 4 related files and my main objective is to look for common elements in all the four files. I would like to use Hash of hashes here and then include the common elements in other common hash table. For example:

Elements in File1: 1. Hi 2. March 3. Aug 4. Sept 5. Oct Elements in File2: 1. March 2. Hi 3. Bye 4. Aug 5. Dec Elements in File3: 1. Hi 2. March 3. Aug 4. Sept 5. Oct Elements in File4: 1. Hi 2. March 3. Aug 4. Bye 5. Dec

Here is my code

my hoh; my hash; for(my $i = 0; $i <= 3; $i++){ my $condition = "first" if ($i == 0); $condition = "second" if ($i == 1); $condition = "third" if ($i == 2); $condition = "forth" if ($i == 3); ## Reading the file open my $IN, $i.".txt or die $!; while(<$IN>){ chomp($_); my $ele = $_; $hoh{$i}{$_} = 1; ### Look for that element if it exists in $hoh{$i}{$_} if $i >=1 for a +ll $i ## for the first file if (!exists $hash{$_}){ $hash{$_} = 10**$i; } elsif ($i >= 1){ #### code to check the common element in all $i #### if the common element is present then my val = $hash{$_} my newVal = int($val) + 10**$i; $hash{$_} = newVal; } } close($IN); }

I am trying to look for common elements among all the files. Say, if an element is present in all the three file and forth then it should not be counted among the common elements. Therefore my result %hash should have only March, Hi and Aug.

Comment on Hash of hashes: Check if the element is present in previous hash table
Select or Download Code
Re: Hash of hashes: Check if the element is present in previous hash table
by Riales (Hermit) on Apr 03, 2012 at 23:45 UTC

    Do you really need a HoH for this? I'm thinking a hash will suffice. Maybe something like this:

    my %hash = (); foreach my $file (qw/File1 File2 File3 File4/) { my %unique_in_file = (); open(IN, '<', $file); while (<IN>) { chomp; $hash{$_}++ unless $unique_in_file{$_}; $unique_in_file{$_} = 1; } close(IN); } use Data::Dumper; print Dumper(grep { $hash{$_} == 4 } keys %hash);

      Hi Riales,

      Thanks for the reply. I am interested to know how can traverse with the elements when there is HoH since i need to the certain operation. Thanks again !!

by graff (Chancellor) on Apr 04, 2012 at 03:08 UTC
    A few suggestions:
    • You shouldn't post code containing obvious syntax errors (unless you can't figure out how to fix them; in that case you should say that you're having trouble getting the syntax right).
    • You should use proper indentation.
    • When you present sample data with your code, the data should be consistent with what the code expects -- the code and data that you post should work together (unless you can't figure out why they don't work together; in that case the data you post should accurately reflect the data you actually have, and you should say you're having trouble handling it properly).

    All that aside, I agree with Riales: the problem as stated in the OP can be solved with a simple hash. If you don't agree, then you must have some problem other than the one you described in the OP.

    Also, I couldn't understand your reply to Riales, so here's an alternate version of the approach he suggested -- if you still have some problem that this doesn't solve, you'll need to describe that other problem.

    I'll base the input data handling on the sample data as you presented it (rather than on the OP code snippet):

    use strict; use warnings; my %words; for my $fnum ( 1 .. 4 ) { open( I, '<', "File$fnum.txt" ) or die "File$fnum.txt: $!\n"; while (<I>) { chomp; s/^[\s\d.]+//; # remove initial digit(s), period, whitespace, + if any $words{$_} .= $fnum unless ( exists( $words{$_} ) and $words{$_} =~ /$fnum$/ ) +; } } print "Words found in all four input files:\n"; for ( sort keys %words ) { print "$_\n" if ( $words{$_} eq '1234' ); }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://963332]
Approved by planetscape
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (13)
As of 2014-03-17 20:34 GMT
Find Nodes?
    Voting Booth?

    Have you used a cryptocurrency?

    Results (358 votes), past polls