Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

sorting hashes

by Angharad (Pilgrim)
on Mar 24, 2009 at 16:43 UTC ( [id://752919]=perlquestion: print w/replies, xml ) Need Help??

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

I have a hash that looks like this.
number -> $cols[0] scorecons -> $cols[1] alignment -> $cols[2]
How might I print the hash sorted on the element 'number'? I'm sure its a simple sort thing but i'm simply not understanding the examples I'm reading on my internet searches. Thanks

Replies are listed 'Best First'.
Re: sorting hashes
by moritz (Cardinal) on Mar 24, 2009 at 16:45 UTC
Re: sorting hashes
by AnomalousMonk (Archbishop) on Mar 24, 2009 at 19:45 UTC
    I am not sure I understand what you require, but if it is "How might I sort the keys or values of a hash by the index in the  @cols array of the value of the hash element", then it is necessary to first make a mapping of the elements of the  @cols array to their indices: another hash.

    Once you have the element-to-index mapping of the array, it is straightforward to sort the keys or values of the original hash by these indices.

    >perl -wMstrict -le "my @cols = qw(bar wobble mosh hop); my %hash = ( wibble => $cols[1], foo => $cols[0], hip => $cols[3], mish => $cols[2], ); my %i_map = map { $cols[$_] => $_ } 0 .. $#cols; print join ' ', qq{keys sorted by \@cols index of value: \n}, sort { $i_map{ $hash{$a} } <=> $i_map{ $hash{$b} } } keys %hash ; print join ' ', qq{values sorted by \@cols index of value: \n}, sort { $i_map{$a} <=> $i_map{$b} } values %hash ; " keys sorted by @cols index of value: foo wibble mish hip values sorted by @cols index of value: bar wobble mosh hop
    The preceding assumes that every value of the hash is an element of the array; it would be wise to validate this assumption.
Re: sorting hashes
by davido (Cardinal) on Mar 24, 2009 at 20:21 UTC

    I started working up an example solution and quickly realized that I'm unclear on your specification. The question I have is this: Does your hash look like this:

    my %hash; @hash{ qw/number score alignment/ } = @cols;

    Or does it look like this:

    my %hash; @hash{ qw/number score alignment/ } = map{ \$cols[$_] } 0 .. $#cols;

    Or does it look like this:

    my %hash = ( number => '$cols[0]', scorecons => '$cols[1]' alignment => '$cols[2]' );

    In other words, is $cols[0] to be represented in your hash as the value of $cols[0], as a reference to the element (ie, \$cols[0]), or as the literal string '$cols[0]? The last option is unlikely, but the first two are not unreasonable interpretations of your question, and yet they change the look of any example solution.

    Please clarify a little for us. Until we have that ironed out we can't really show you how the solution might look.

    Also remember that Perl's hashes are unsorted by definition. If you need to present the contents of a hash in some sorted order, you can do that on the fly, but keep in mind that if you refer back to that sorted order frequently you might find it convenient to maintain a separate sorted list; a parallel list, so to speak. In fact, your @cols array could even be an AoA that keeps track of keys and values in a sorted order such as:

    @cols = ( [ qw/value1 number / ], [ qw/value2 scorecons/ ], [ qw/value3 alignment/ ] );

    You could still maintain the hash too for quick lookups.


    Dave

Re: sorting hashes
by bichonfrise74 (Vicar) on Mar 25, 2009 at 01:34 UTC
    If I understand your question... I would write it in this manner.
    #!/usr/bin/perl use strict; my %old_hash = ( 'number' => '5', 'cat' => '3', 'dog' => '2' ); my %new_hash = reverse %old_hash; my @sort_arrays = map { $old_hash{$_} } sort { $old_hash{$a} <=> $old_hash{$b} } (keys %old_hash); print "$new_hash{$_} -> $_\n" for (@sort_arrays);

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-25 16:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found