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

Oh great masters...please honor me with your wisdom.. I have to do a sort on a number field....similar to (123/4568), the sort will be made on the numbers to the left of the / and then reconnected. The numbers on both sides of the / are never the same size, and can be as long as 5 digits.....please help me.......

Replies are listed 'Best First'.
(tye)Re: divide by '/'
by tye (Sage) on Apr 11, 2001 at 08:08 UTC

    Personally, I think I'd just go for:

    my @sort= do { local( $^W )= 0; sort {$a<=>$b} @list; }
    Those strings in a numeric context will compare properly but would produce warnings so I disable warnings. Also, each strings will only be converted to a number once after which that value will be cached in the SV (scalar value) making later comparisons as fast as is possible in Perl.

            - tye (but my friends call me "Tye")
Re: divide by '/'
by stephen (Priest) on Apr 11, 2001 at 03:20 UTC
    So, if I'm reading this right, you've got a bunch of numbers like so:
    64/2829 1/349834 37823/8338 5/989328
    And you want them sorted like this:
    1/349834 5/989328 64/2829 37823/8338
    Here:
    sub sortbyfirst { my ($f_a, undef) = split(/\//, $a); my ($f_b, undef) = split(/\//, $b); return $f_a <=> $f_b; } @sorted = sort sortbyfirst @numbers;

    Note: Untested.

    This won't be superfast... If you've got a huge list, or this runs constantly, look into the tye transductor, illustrated here.

    stephen

Re: divide by '/'
by dws (Chancellor) on Apr 11, 2001 at 04:09 UTC
    @numbers = qw( 1/23 3/45 65/0 6/01 0/100 123/4568 ); @sorted = sort { (split('/', $a))[0] <=> (split('/', $b))[0] } @numbers; print "@numbers\n";

    Very embarrassing update: That last line should indeed read print "@sorted\n"; Thanks to jynx for the /msg.


      Did you mean:
      print "@sorted\n";
      For that last line?

      jynx

        Yup. Stringifying the array automatically uses $" ($LIST_SEPARATOR if you use English;) as a separator. It's a shortcut for saying   print join($", @sorted), "\n"; which, since $" defaults to ' ', is a also a shortcut for   print join(' ', @sorted), "\n";
Re: divide by '/'
by idnopheq (Chaplain) on Apr 11, 2001 at 03:36 UTC
    I went with a split, hash, and sort method.

    #!/usr/bin/perl -w # slurped file in @numbers # final outcome in %numHash @numbers = ( "432/205", "905/4578", "623/4568", "1/10009", "10/10005" +); foreach ( @numbers ) { ($key, $value) = split /\//, $_; $numHash{$key} = $value; } # UPDATED foreach $numerator ( sort { $a <=> $b } keys %numHash ) { print $numerator , '/' , $numHash{$numerator} , "\n"; }

    TIMTOWTDI
    Dex

    p.s. - mine won't handle leading zeros, but the pizza man is en route!

    UPDATE 0: - forgot my <=>!!!!! Need fud!

    UPDATE 1: - check out how do i sort hash by key numerically

Re: divide by '/'
by astanley (Beadle) on Apr 11, 2001 at 03:13 UTC
    I'm not quite sure what you're saying you need to do...but getting and sorting the numbers should be simple. Just put both into it's own array, ie:
    my (@left, @right) = (); foreach (@field) { m/\(([0-9]+)\/([0-9]+)\)/; my $leftnum = $1; my $rightnum = $2; push(@left, $leftnum); push(@right, $rightnum); }
    once you have all the values in seperate arrays - just run the sort function on each.
    I think that's what you were trying to say....once they're sorted you can put them back together or do whatever else you wish to do to them.

    -Adam Stanley
    Nethosters, Inc.
Re: divide by '/'
by cLive ;-) (Prior) on Apr 11, 2001 at 04:51 UTC
    Update: Oops, just realised that my reply was exactly the same as the one by [id://dws] above.

    weird...

    cLive ;-)