Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Sort not acting as expected on Hash Ref

by oakbox (Chaplain)
on Jan 01, 2003 at 11:18 UTC ( #223561=perlquestion: print w/replies, xml ) Need Help??

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

Sort isn't acting like I expect it to and I'm a little confused. I have a hash reference that looks like this:
$sort_line_contents->{element_one}->{element_two}

I want to reverse sort on element_one (numerically) and then sort normally on element_two. Here is an example of my data set:

$sort_line_contents->{1}->{2} = Item1; $sort_line_contents->{0}->{3} = Item2; $sort_line_contents->{1}->{4} = Item3; $sort_line_contents->{1}->{5} = Item4; $sort_line_contents->{2}->{6} = Item5;

I want to take that information and force it into an order like this:
Item5
Item1
Item3
Item4
Item2

My first crack at this was using a sort statement like so:

my @hash_keys2 = sort { %{$sort_line_contents}->{$b} <=> %{$sort_li +ne_contents}->{$a} } keys %{$sort_line_contents};

But this gives me an incorrect order. Instead of giving me an order like this: 2, 1, 1, 1, 0 it gives me something like 0, 2, 1, 1, 1. I could not get this straightened out, so eventually ended up substituting this line:
foreach (reverse sort keys %{$sort_line_contents}) { push(@hash_keys2, +$_);}
I'm even more confused because the second sort using the second value works AS EXPECTED:
foreach my $hk (@hash_keys2){ my @filli = sort { $sort_line_contents->{$hk}->{$a} <=> $sort_li +ne_contents->{$hk}->{$b} } keys %{$sort_line_contents->{$hk}}; foreach (@filli){ #output to other part of program } }
My question is, why doesn't the sort on the hash ref give me the expected behaviour? Is there a problem with the way I am expanding my $sort_line_contents reference? I see that it is reading out the correct VALUES, it is just putting them in an unexpected order. I get the same unexpected order with the <=> and the cmp operators???

oakbox

Replies are listed 'Best First'.
Re: Sort not acting as expected on Hash Ref
by gjb (Vicar) on Jan 01, 2003 at 11:37 UTC

    Try this:

    foreach my $key (sort {$b <=> $a} keys %$sort_line_contents) { print join("\n", values %{$sort_line_contents->{$key}}), "\n"; }
    First the keys are sorted, and for each of those, all values are printed.

    Hope this helps, -gjb-

Re: Sort not acting as expected on Hash Ref
by jdporter (Canon) on Jan 02, 2003 at 04:53 UTC
    What you have is really a reference/dereferencing problem, more than a sort problem. The sorts are simple enough, it's the ref stuff that's tricky.

    I believe this will do what you want:
    for my $e1 ( sort { $b <=> $a } keys %$sort_line_contents ) { for my $e2 ( sort keys %{ $sort_line_contents->{$e1} } ) { print $sort_line_contents->{$e1}->{$e2}, "\n"; } }

    jdporter
    The 6th Rule of Perl Club is -- There is no Rule #6.

Re: Sort not acting as expected on Hash Ref
by PodMaster (Abbot) on Jan 01, 2003 at 11:29 UTC
    Do you know what scalar %{$foo->{1}} gets you if $foo = { 1 => { 6,7 } , 2 => { 66,77 } };?

    I believe you simply want compare

    $foo->{$b} <=> $foo->{$a}


    MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
    ** The Third rule of perl club is a statement of fact: pod is sexy.

      In a scalar context, hash would be evaluated to a fraction, which represents "number of buckets used" out of "number of buckets allocated". So it would be some kind of order related to memory usage.

      However what we got is a string representation of a fraction, so the order is not quite right, for example 13/16 would be less than 2/16.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (9)
As of 2020-04-08 18:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The most amusing oxymoron is:
















    Results (45 votes). Check out past polls.

    Notices?