Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

sorting question

by chinman (Monk)
on Oct 17, 2004 at 19:29 UTC ( [id://399954]=perlquestion: print w/replies, xml ) Need Help??

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

Brethren,

I have a reference to a 2-D array ($xy) of floats. I would like to sort the y values (in descending order), but ideally I would like the x values to follow the sorting of y. One implementation that I came up with uses a hash as shown below to make a new array of x values that follows the y sort, but I'm sure there's a more efficient way to do this. My 2-D array can be pretty large (10k - 100k data points), so I'm interested in speed. Thanks for your suggestions.

my @x = @{$xy->[0]}; my @y = @{$xy->[1]}; my $i = 0; my %xyhash; foreach ( @x ) { $xyhash{ $_ } = $y[$i]; $i++ } my @x_sorted_by_y = sort{ $xyhash{$b} <=> $xyhash{$a} } keys %xyhash; my @sorted_y = sort{ $b <=> $a } @y; print "value of x with largest y = $x_sorted_by_y[0]\n"; print "largest y = $sorted_y[0] \n";

Regards chinman

Replies are listed 'Best First'.
Re: sorting question
by Enlil (Parson) on Oct 17, 2004 at 20:04 UTC
    This assumes you will have the same amount of x's as y's or you'll get a whole lot of uninitialized warnings (granted there are ways around that):
    use strict; use warnings; my $xy = [ [5,4,2,3,1,12], [2,9,2,3,4,5] ]; my @xy; #push x's and corresponding y coor. in #a slight different AoA; for ( 0 .. $#{$xy->[0]} ){ push @xy, [ $xy->[0][$_], $xy->[1][$_] ]; } #sort it by y; @xy = sort { $a->[1] <=> $b->[1] } @xy; print "value of x with largest y = $xy[-1][0]\n"; print "largest y = $xy[-1][1]\n";
Re: sorting question
by johnnywang (Priest) on Oct 17, 2004 at 19:59 UTC
    use strict; my $xy = [[1,2,3,4,5],[4,2,5,0,2]]; my @sorted = sort{$b->[1]<=>$a->[1] ||$b->[0]<=>$a->[0]} map{[$xy->[0] +->[$_],$xy->[1]->[$_]]} (0..$#{$xy->[0]}); print "($_->[0],$_->[1])\n" foreach @sorted;
Re: sorting question
by dave_the_m (Monsignor) on Oct 17, 2004 at 19:50 UTC
    @sorted_xy = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @xy;
    or threreabouts

    update:

    I misinterpreted the structure of $xy; I thought it was a list of coordinate pairs. Use one of the other solutions instead!

    Dave.

Re: sorting question
by chinman (Monk) on Oct 17, 2004 at 20:44 UTC
    Thanks everyone for the suggestions! Your suggestions are about twice as fast as the way I was attempting to do it.

    Regards chinman

Re: sorting question
by TedPride (Priest) on Oct 17, 2004 at 23:14 UTC
    I could be wrong, but it looks like you are using coordinate pairs. The following sorts coordinate pairs with y in descending order and x in ascending (since you didn't specify x to be descending as well):
    use strict; use warnings; my ($x, $y, $ref); for (0..20) { # Randomize some data points for testing $x = int rand 100; $y = int rand 100; $ref->[$_] = [$x,$y]; } for (sort {$b->[1] <=> $a->[1] or $a->[0] <=> $b->[0]} @$ref) { print $_->[0] . ',' . $_->[1] . "\n"; }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2025-07-19 13:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.