Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

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

...................TQ

Comment on sorting not sort
Download Code
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 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.


    Dave

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

    Hi,

    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
    

      Sorry!

      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 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 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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (14)
As of 2014-09-22 13:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (191 votes), past polls