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

Hi Monks, I have a file:
10|name 8|name 12|name
Iwould like to sort it by the value. I have tried the following but it doesnt sort by numerical order?
%name; { while (<>) { ($number, $filename) = split (/\|/, $_); print "$number\n"; $name{$number}=$filename; } } foreach $number (sort (keys(%name))) { print "\t$number\t\t$name{$number}\n"; }

Replies are listed 'Best First'.
Re: sorting a hash by key
by ikegami (Patriarch) on Aug 04, 2005 at 15:16 UTC
    You're sorting alphatically. Use
    foreach $number (sort { $a <=> $b } keys(%name)) {
    to sort numerically.
Re: sorting a hash by key
by rinceWind (Monsignor) on Aug 04, 2005 at 15:19 UTC

    The default collating sequence for sort is ASCII (cmp). If you want something different, you have to tell sort how to compare two items.

    foreach $number (sort {$a <=> $b} (keys(%name))) {

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

      thanks for ur help. quite new to hashes, proving very useful little things
Re: sorting a hash by key
by davido (Cardinal) on Aug 04, 2005 at 15:22 UTC

    Your node title says you wish to sort by key. Your question says you would like to sort by value. And your script is sorting by key. 2:1, I'm going to assume you wish to sort by key. In that case, your problem is that you're doing an ascii-betical sort instead of a numeric sort. Try this:

    foreach $number ( sort { $a <=> $b } keys %name ) { print "\t$number\t\t$name{$number}\n"; }

    You may have another problem too. Hash keys are unique. That means you can only have one of each 'number'. You're ok if you keep that in mind. But if the numbers represent, for example, scores, it would be possible that different names are associated with the same numbers, in which case you lose some filenames when converting to a hash. This may not be an issue for you. In your example file it looks (from the three lines you showed) like there are no duplicate numbers. Just make sure that's really the case.

    Also, don't forget to chomp before splitting, unless you want your filenames to come with newlines attached to them.


    Dave

Re: sorting a hash by key
by Taulmarill (Deacon) on Aug 04, 2005 at 15:25 UTC
      always on
Re: sorting a hash by key
by davidrw (Prior) on Aug 04, 2005 at 16:18 UTC
    don't know your context here, but can you just do this on the commandline?
    sort -n /tmp/data # make sure that it's a real tab char in there for the output # note different sort params as example sort -t '|' -k 1 -n /tmp/data | cut -d '|' --output-delimiter=' ' + -f 1,2 # and to completely mimic the output of your code: sort -n /tmp/data | perl -F'\|' -nae 'print "\t$F[0]\t\t$F[1]";' sort -n /tmp/d | awk -F \| '{ print "\t" $1 "\t\t" $2 }'