Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

sorting not sort

by Anonymous Monk
on Aug 29, 2005 at 07:35 UTC ( #487351=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Below is my code;-
$strings{"E1,E2"} = $afinity12c; $strings{"E1,E3"} = $afinity13c; $strings{"E1,E4"} = $afinity14c; $strings{"E1,E5"} = $afinity15c; $strings{"E1,E6"} = $afinity16c; $strings{"E1,E7"} = $afinity17c; $strings{"E1,E8"} = $afinity18c; $strings{"E1,E9"} = $afinity19c; $strings{"E1,E10"} = $afinity110c; print map{ "$_ = $strings{$_}\n <p>" } sort{ $strings{$b} <=> $strings{$a} } keys %strings;
The problem is it sort the number but not the string

the output will be

E1,E2 = 1

E1,E5 = 0.7

E1,E3 = 0.7(should E1,E5 is before E1,E5)

E1,E7 = 0.7


Comment on sorting not sort
Download Code
Replies are listed 'Best First'.
Re: sorting not sort
by davido (Archbishop) on Aug 29, 2005 at 07:45 UTC

    So you want to sort by affinity first, and by string second?

    print map{ "<p> $_ = $strings{$_} </p>\n" } sort{ $strings{$b} <=> $strings{$a} or $a cmp $b } keys %strings;

    I think that's what you're asking for. By the way, have you had a chance to read the documentation for sort yet? It can prove helpful.

    Also note, it's a big mistake to start naming your variables $afinity1c, $afinity2c, $afinity3c ... $afinity200c. That's going to lead you down a road toward a desire to use symbolic references, and that road leads to hell (or worse!). Use an array when you want an array. perlintro discusses the basics of arrays and hashes.


Re: sorting not sort
by Roger (Parson) on Aug 29, 2005 at 08:42 UTC
    You can put multiple conditions in the sort, using the || operator, so that when the first rule is equal (ie, =0), the second rule will kick in, otherwise take the first rule.

    $strings{"E1,E2"} = 1; $strings{"E1,E3"} = 3; $strings{"E1,E4"} = 2; $strings{"E1,E5"} = 3; $strings{"E1,E6"} = 3; $strings{"E1,E7"} = 5; $strings{"E1,E8"} = 1; $strings{"E1,E9"} = 0; $strings{"E1,E10"} = 12; my @sorted = map { $_->[0] } sort { ($b->[2] <=> $a->[2]) || ($a->[1] <=> $b->[1]) } map { my $old_key = $_; # transform my keys so I can compare them as digits my ($k1, $k2) = $old_key =~ /(\d)/g; my $new_key = sprintf("%04d%04d", $k1, $k2); [ $old_key, $new_key, $strings{$old_key} ] } keys %strings; print map{ "$_ = $strings{$_}\n" } @sorted;

Re: sorting not sort
by gargle (Hermit) on Aug 29, 2005 at 08:19 UTC


    I was just wondering why you'd not use a hash in a hash? I'd propose the following:

    #!/usr/bin/perl use strict; use warnings; my $string = { index1 => { index11 => 4 }, index2 => { index21 => 3 , index22 => 2 }, index3 => { index31 => 1 } }; for my $i (sort keys %$string) { my $tmp = $string->{$i}; for my $j (sort keys %$tmp) { print $i . " " . $j . " " . $string->{$i}->{$j} . "\n"; } }

    index1, index2, index3 and so on are just names I made up to fill the hash with something. You can replace them with your E1's, E2's, etc... The nested for loops sort in ascending order.

    The hash in a hash for gives the following output:

    index1 index11 4
    index2 index21 3
    index2 index22 2
    index3 index31 1


      I just re-read your question. If there is a need to sort the values first it's easier not to pass thru a hash in a hash.

      I've should have read the question better. Guess it's too early :(

Re: sorting not sort
by Anonymous Monk on Aug 29, 2005 at 07:36 UTC
    The question is how do I sort the 'name' after I sort the number? TQ
Re: sorting not sort
by ysth (Canon) on Aug 29, 2005 at 23:23 UTC
    You seem to have some fundamental confusions. Your code, as is, does a descending numeric sort by the values in %strings, while what you are describing is an ascending mixed numeric/string sort of the keys.

    To do the latter, you need to provide a lot more code to sort. Here's one way:

    sub sortable_key { my $key = shift; # e.g. "E1,E10"; $key =~ s/(\d+)/ chr($1+0x1000000) /e; return $key; } print map { "$_ = $strings{$_}\n" } sort { sortable_key($a) cmp sortable_key($b) } keys %strings;

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (16)
As of 2016-02-11 17:43 GMT
Find Nodes?
    Voting Booth?

    How many photographs, souvenirs, artworks, trophies or other decorative objects are displayed in your home?

    Results (377 votes), past polls