Sorting Hash by Value and Key

Discussion in 'Perl Misc' started by vunet.us@gmail.com, May 17, 2007.

  1. Guest

    Could someone show how to sort my hash by values (primary sorting) and
    then by key for the same values:

    %grades = (
    0 => 70,
    1 => 50,
    6 => 90,
    5 => 90,
    4 => 90,
    );

    I want to see:
    1 => 50
    0 => 70
    4 => 90
    5 => 90
    6 => 90

    Thank you
     
    , May 17, 2007
    #1
    1. Advertising

  2. On 17 May 2007 06:57:20 -0700, wrote:

    >Could someone show how to sort my hash by values (primary sorting) and
    >then by key for the same values:


    You can't sort a *hash*. I suppose you want to sort its keys(). Don't
    you?

    >%grades = (
    > 0 => 70,
    > 1 => 50,
    > 6 => 90,
    > 5 => 90,
    > 4 => 90,
    >);
    >
    >I want to see:
    > 1 => 50


    A hash is intrinsically unsorted. Get a list of arrayrefs instead.

    > 0 => 70


    Are you sure you want a hash, anyway? Those keys seem to better suited
    for a regular array.

    > 4 => 90
    > 5 => 90
    > 6 => 90


    What have you tried thus far? Well, let's spoon-feed you anyway:

    my @sorted=sort {$a->[1] <=> $b->[1] or $a->[0] <=> $b->[0]}
    map [$_ => $grades{$_}], keys %grades;


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, May 17, 2007
    #2
    1. Advertising

  3. >>>>> "v" == vunet us <> writes:

    v> Could someone show how to sort my hash by values (primary
    v> sorting) and then by key for the same values:

    Because of the way hashes are represented internally, it is
    inefficient to maintain them in a sorted order. In other words, you
    can't sort a hash. (You can in other languages, yes. If you want
    them, you know where to find them.)

    What you *can* do is sort a list of hash keys based on the values they
    have in a particular hash. See perldoc perlfaq4 under "How do I sort
    a hash (optionally by value instead of key)?"

    Charlton


    --
    Charlton Wilbur
     
    Charlton Wilbur, May 17, 2007
    #3
  4. Mirco Wahab Guest

    wrote:
    > Could someone show how to sort my hash by values (primary sorting) and
    > then by key for the same values:
    >
    > %grades = (
    > 0 => 70,
    > 1 => 50,
    > 6 => 90,
    > 5 => 90,
    > 4 => 90,
    > );
    >
    > I want to see:
    > 1 => 50
    > 0 => 70
    > 4 => 90
    > 5 => 90
    > 6 => 90


    In addition to the solutions and hints given
    already by Michele and Charlton, you could
    simply construct another hash which holds
    your sort criteria as the 'key', like


    my %grades = (
    0 => 70, 1 => 50,
    6 => 90, 5 => 90,
    4 => 90 );

    my %hsort= map +($grades{$_}.$_,$_), keys %grades;

    print "$hsort{$_} $grades{ $hsort{$_} }\n" for sort keys %hsort;



    more another solutions of course possible.

    Regards

    M.
     
    Mirco Wahab, May 17, 2007
    #4
  5. Guest

    spoon-feeding did not work for me. this is my first perl file but i do
    try hard anyway. Micro's solution did not sort right (for me) and
    Michele's solution i cannot print.
    anyway, my goal is (after your feedback) to sort all values and then
    sort only thoses keys whose values are the same. example:

    %grades = (
    0 => 1,
    7 => 2,
    6 => 3,
    5 => 4,
    8 => 5,
    9 => 6, _______<<
    1 => 7,
    2 => 7,
    3 => 7,
    4 => 7,
    );

    PS: YES, I need to print, not sort a hash itself.
    Thanks
     
    , May 17, 2007
    #5
  6. Mirco Wahab Guest

    wrote:
    > spoon-feeding did not work for me. this is my first perl file but i do
    > try hard anyway. Micro's solution did not sort right (for me) and
    > Michele's solution i cannot print.
    > anyway, my goal is (after your feedback) to sort all values and then
    > sort only thoses keys whose values are the same. example:


    OK, so you want a numerical sort on the values and
    then (if equal) a numerical sort on the keys?

    You need to employ an extra array of the keys combined
    with a sort function, which does what you want, like

    ...

    my %grades = (
    0 => 1,
    9 => 6,
    1 => 7,
    2 => 7,
    3 => 7,
    7 => 2,
    6 => 3,
    5 => 4,
    8 => 5,
    4 => 7 );

    my @hsort =
    sort { $grades{$a} <=> $grades{$b} || $a <=> $b }
    map $_,
    keys %grades;

    print "$_ => $grades{$_}\n" for @hsort;

    ...


    In Perl, you have to look hard if your comparison
    compares strings (characters) or numeric values.

    Regards

    Mirco
     
    Mirco Wahab, May 17, 2007
    #6
  7. Mirco Wahab Guest

    Mirco Wahab wrote:
    > my @hsort =
    > sort { $grades{$a} <=> $grades{$b} || $a <=> $b }
    > map $_,
    > keys %grades;


    WTF did I smoke here :)

    the line

    > map $_,


    is of course superfluous

    Sorry,

    M.
     
    Mirco Wahab, May 17, 2007
    #7
  8. Guest

    On May 17, 2:36 pm, Mirco Wahab <> wrote:
    > wrote:
    > > spoon-feeding did not work for me. this is my first perl file but i do
    > > try hard anyway. Micro's solution did not sort right (for me) and
    > > Michele's solution i cannot print.
    > > anyway, my goal is (after your feedback) to sort all values and then
    > > sort only thoses keys whose values are the same. example:

    >
    > OK, so you want a numerical sort on the values and
    > then (if equal) a numerical sort on the keys?
    >
    > You need to employ an extra array of the keys combined
    > with a sort function, which does what you want, like
    >
    > ...
    >
    > my %grades = (
    > 0 => 1,
    > 9 => 6,
    > 1 => 7,
    > 2 => 7,
    > 3 => 7,
    > 7 => 2,
    > 6 => 3,
    > 5 => 4,
    > 8 => 5,
    > 4 => 7 );
    >
    > my @hsort =
    > sort { $grades{$a} <=> $grades{$b} || $a <=> $b }
    > map $_,
    > keys %grades;
    >
    > print "$_ => $grades{$_}\n" for @hsort;
    >
    > ...
    >
    > In Perl, you have to look hard if your comparison
    > compares strings (characters) or numeric values.
    >
    > Regards
    >
    > Mirco


    Ideal, thanks
     
    , May 17, 2007
    #8
  9. On Thu, 17 May 2007 21:04:33 +0200, Mirco Wahab <>
    wrote:

    >WTF did I smoke here :)
    >
    >the line
    >
    > > map $_,

    >
    >is of course superfluous


    STS? (Schwartzian Transform Syndrome?)

    Kinda reminds me of when I discovered the calculus of residues. I was
    so fond of it that at some time I found myself applying it to an
    integral which, after the work was done... I realized was a trivial
    one!


    Michele
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
     
    Michele Dondi, May 17, 2007
    #9
  10. On 17 May 2007 06:57:20 -0700,
    <> wrote:
    > Could someone show how to sort my hash by values (primary sorting) and
    > then by key for the same values:


    In addition to the answers you already have, you should probably also
    have a look in the FAQ, section 4, as that answers your question:

    How do I sort a hash (optionally by value instead of key)?

    and also

    How do I sort an array by (anything)?

    This FAQ also refers to the 'far more than you ever wanted to know'
    document on sorting at http://www.perl.com/CPAN/doc/FMTEYEWTK/sort.html

    Martien
    --
    |
    Martien Verbruggen | "In a world without fences,
    | who needs Gates?"
    |
     
    Martien verbruggen, May 17, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Me
    Replies:
    2
    Views:
    710
    Michael Beattie
    Jan 26, 2005
  2. vikas
    Replies:
    3
    Views:
    520
    CBFalconer
    Aug 16, 2007
  3. rp
    Replies:
    1
    Views:
    557
    red floyd
    Nov 10, 2011
  4. Une bévue
    Replies:
    5
    Views:
    156
    Une bévue
    Aug 10, 2006
  5. Antonio Quinonez
    Replies:
    2
    Views:
    180
    Antonio Quinonez
    Aug 14, 2003
Loading...

Share This Page