in reply to beginner - ordering tuples

Trying to make it as simple as possible, I used List::Tuples and the builtin sort function.

First, we'll assume that the inputs are unordered, so we'll use a numerically-ascending sort:

my @sorted_numbers = sort {$a <=> $b} @numbers
Then diving head-first into List::Tuples:
#!/usr/bin/perl use strict; use warnings; use List::Tuples qw(:all); use Data::Dumper::Concise; my @numbers = qw(10 1 12 5 20 7); my @sorted_numbers = sort { $a <=> $b } @numbers; my @tuples = tuples[2] => (@sorted_numbers); print Dumper(@tuples);

Replies are listed 'Best First'.
Re^2: beginner - ordering tuples
by Anonymous Monk on Nov 13, 2010 at 13:19 UTC
    Thanks for your reply. I've actually used the solution given above my rolf and it works great. However I have now found an additional need for the ordering: If some tuples have the same number on the first position I need them to be ordered so that the HIGHEST number in the second position comes first
    e.g. <12, 34> <12, 43> <12,10> becomes <12,43> <12,34> <12,10>
    I couldn't modify the code to get it to do what I wanted
      do you mind if I simplify it to a one liner?

      use strict; use warnings; my @datas; # for (<DATA>){ # push @datas, [ m/<(\d+),(\d+)>/ ]; # } @datas = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } map { [ m/<(\d+),(\d+)>/ ] } <DATA>; use Data::Dumper; print Dumper \@datas; __DATA__ <7,22> <12,20> <7,15> <1,5> <7,10>

      please see sort about how the boolean three states condition decides about the ordering.

      the perlop || is - like in C - short circuiting, that is the RHS is only evaluated (and returned) when the LHS is false (i.e 0 if <=> compares equal values).

      If your tuples have more than 2 elements you should ask for a generic solution.

      Cheers Rolf

        In your elegant solution, you need to switch around your second conditional to:

        $b->[1] <=> $a[1]
      I modified the above as follows but it will probably make you perl programmers cringe with despair. Sorry rolf for desecrating your original answer :)
      use strict; use warnings; $" = ', '; my @datas; #- parse input for (<DATA>){ my @entries = m/<(\d+),(\d+)>/; push @datas, [@entries]; } #- sort @datas=sort sort_test @datas; #- output use Data::Dumper; print Dumper \@datas; sub sort_test() { if ($a->[0] < $b->[0]) { return -1; }elsif ($a->[0] > $b->[0]){ return 1 }else { if ($a->[1] > $b->[1]) { return -1; } elsif ($a->[1] < $b->[1]) { return 1; } else { return 0; } } } __DATA__ <12,20> <1,5> <7,10> <7,12> <7,15>
        I've just noticed, why has it put some of the output in single quotes: (look at the first and last one). I did it with different data and the last 2 tuples had quotes around the second value.
        $VAR1 = [ [ 1, '5' ], [ 7, 15 ], [ 7, 12 ], [ 7, 10 ], [ 12, '20' ] ];