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

Greetings, fellow monks.

I'm working with a script that was made by a colleague in the company that displays three hashes.

I need to turn them into one sorted hash, but I'm failing to do so. Please show me the way.

What I have now is something like this:
# hash 1 2 cars 1 motorcycle 4 balloons #hash 2 5 airplanes 3 helicopters 6 skateboards
... and so on. What I need is something like:
#hash 1 motorcycle 2 cars 3 helicopters 4 balloons 5 airplanes 6 skateboards
I know this question seems simple, but imagine that the real thing is a database with dozens of items in every hash...

I've tried to concatenate them, but Perl tells me that's impossible. Is there any workarounds, tricks, tips?

I also know that maybe this is not the best way to do it, but since the whole application is almost fully developed, I need to work with this code as it is. Maybe later I get time to improve it. At least I hope so...

Thanks a lot for your help, my fellow monks.

humbly yours,

Er Galvão Abbott
a.k.a. Lobo, DaWolf
Webdeveloper

Replies are listed 'Best First'.
Re: Multiple Hashes are stressing me
by blakem (Monsignor) on Oct 09, 2001 at 04:14 UTC
    How about:
    %bighash = (%hash1,%hash2,%hash3);
    Note that any duplicate keys will collide, and the value will be that of the the right most hash value... i.e. $hash3{dupe} will take precedence over $hash2{dupe} will take precedence over $hash1{dupe}.

    Here is an example:

    #!/usr/bin/perl -wT use strict; my %hash1 = (2 => 'cars', 1 => 'motorcycle', 4 => 'balloons', 9 => 'came from hash1'); my %hash2 = (5 => 'airplanes', 3 => 'helicopters', 6 => 'skateboards', 9 => 'came from hash2'); my %bighash = (%hash1 , %hash2); # combine the two hashes print "Hash1\n"; print "\t$_ => $hash1{$_}\n" for (sort {$a<=>$b} keys %hash1); print "Hash2\n"; print "\t$_ => $hash2{$_}\n" for (sort {$a<=>$b} keys %hash2); print "BigHash\n"; print "\t$_ => $bighash{$_}\n" for (sort {$a<=>$b} keys %bighash); =OUTPUT Hash1 1 => motorcycle 2 => cars 4 => balloons 9 => came from hash1 Hash2 3 => helicopters 5 => airplanes 6 => skateboards 9 => came from hash2 BigHash 1 => motorcycle 2 => cars 3 => helicopters 4 => balloons 5 => airplanes 6 => skateboards 9 => came from hash2

    -Blake

      Is it that simple?

      Man, I'm really embarassed...

      Thanks a lot, Blake. I'll test it tomorrow at work.

      Best Regards,

      Er Galvão Abbott
      a.k.a. Lobo, DaWolf
      Webdeveloper
        Whats actually happening is that the hashes are flattened into a list, then this list is assigned to a new hash. So, %h1 and %h4 wind up with the same contents below:
        #!/usr/bin/perl -wT use strict; my @a1 = ('jan','January','feb','February'); my @a2 = ('mar','March', 'apr','April'); my %h1 = (@a1, @a2); # Two arrays become one h +ash my %h2 = ('jan','January','feb','February'); my %h3 = ('mar'=>'March' ,'apr'=>'April'); # '=>' is really just a c +omma my %h4 = (%h2,%h3); # Hashes get flattened an +d behave # nearly the same as the +two # arrays did above print "h1\n"; print "\t$_ => $h1{$_}\n" for (sort keys %h1); print "h4\n"; print "\t$_ => $h4{$_}\n" for (sort keys %h4); =OUTPUT h1 apr => April feb => February jan => January mar => March h4 apr => April feb => February jan => January mar => March

        -Blake

        Yes, it gets easier once you realize that you don't have to micromanage your data, like in C.

Re: Multiple Hashes are stressing me
by Zaxo (Archbishop) on Oct 09, 2001 at 04:47 UTC

    Hashes are inherently unsorted, so let's seperate combining the hashes from sorting and printing them:

    #!/usr/bin/perl -w use strict; my %hash1 = qw( 2 cars 1 motorcycle 4 balloons ); my %hash2 = qw( 5 airplanes 3 helicopters 6 skateboards ); # combine my %hash = (%hash1, %hash2); # print sorted print map "$_ $hash{$_}\n", sort {$a<=>$b} keys %hash;
    If you need the sorted keys for more than the print, you could save them in an array of their own.

    After Compline,
    Zaxo

(tye)Re: Multiple Hashes are stressing me
by tye (Sage) on Oct 09, 2001 at 09:39 UTC

    I'm partial to:

    # Append %add to %base: @base{keys %add}= values %add;
    note that for duplicate keys, %add wins in this case, just as if you had done: %base= ( %base, %add ); but the hash slice code should be faster (tho I won't guarentee that, especially not for all cases) since it doesn't have to empty the first hash and then reload it with itself.

            - tye (but my friends call me "Tye")
Re: Multiple Hashes are stressing me
by Anonymous Monk on Oct 09, 2001 at 16:08 UTC
    You could do something like this:
    %hash1 = qw( 
    	2 cars
    	1 motorcycle
    	4 balloons
    	);
    
    %hash2 = qw(
    	5 airplanes
    	3 helicopters
    	6 skateboards
    	);
    
    %hash3 = ( %hash1, %hash2 );
    
    for (sort keys %hash3) {
    	print "$_ => $hash3{$_}\n";
    }