in reply to How would I sort a two-dimensional array by multiple columns?

And if you really want a subroutine...
use Test::More qw/no_plan/; my $unsorted = [ [ qw/1 3 5 6 2/ ], [ qw/3 4 5 6 7/ ], [ qw/1 2 3 4 5/ ], [ qw/5 6 7 8 8/ ], [ qw/1 2 3 4 5/ ], [ qw/2 2 2 2 2/ ], [ qw/1 1 2 4 5/ ], [ qw/2 3 4 5 6/ ], ]; my $expected = [ [ qw/1 1 2 4 5/ ], [ qw/1 2 3 4 5/ ], [ qw/1 2 3 4 5/ ], [ qw/1 3 5 6 2/ ], [ qw/2 2 2 2 2/ ], [ qw/2 3 4 5 6/ ], [ qw/3 4 5 6 7/ ], [ qw/5 6 7 8 8/ ], ]; my $sorted = sortSub($unsorted, 0, 1, 3); is_deeply $sorted, $expected; sub sortSub { my @array = @{ +shift }; my @sorted = sort { for my $ix ( @_ ) { my $cmp = $a->[$ix] <=> $b->[$ix]; return $cmp if $cmp; } return 0; } @array; return \@sorted; }

Update: Fixed a mistake spotted by dbmathis Narveson.

Replies are listed 'Best First'.
Re^2: How would I sort a two-dimensional array by multiple columns?
by Narveson (Chaplain) on Mar 15, 2008 at 21:28 UTC
      Yes, you're right. I'll update the node now.

      Thanks

        There are subtle bugsdifferences in interpretation of the OP's request in both jettero and FunkyMonk's solutions.

        In essence, neither goes deep enough to resolve differences - jettero stops at the second element, and FunkyMonk stops after index 3.

        FunkyMonk - in your code, "@_" inside the sort is probably not what you think it is - at that point, @_ is still the parameter passed into "sortsub". Inside the sort itself, you only have $a and $b. The "@_" comes from the outer sub.

        Here is code with slightly modified data, that demonstrates the errors, and my proposed "correct" solution.

        Update: Updated based on ikegami's note below (return 0, not 1);
        Also updated FonkyMonk's sort - uses @_ instead of 0..@_.

        Update 2: The O.P. has correctly chosen Funkymonk's code as representing what he requested.
        My code addresses a different issue - sorting to the complete depth.

             "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re^2: How would I sort a two-dimensional array by multiple columns?
by dbmathis (Scribe) on Mar 16, 2008 at 03:06 UTC

    How would I make this work if I am passing in @unsorted rather than $unsorted?

    After all this is over, all that will really have mattered is how we treated each other.
      I had already indicated that in the comment of my previous node. Here it is again:
      my @sorted = sort NetWallahSort @unsorted;
      Note : I have updated "sub NetWallahSort" in the posted code, to include ikegami's suggestion, returning "0" instead of "1" when sort elements are equal. Please use a current copy of that code.

           "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

        Sorry NetWallah, I was refering to Funk's code. I saw your previous comment, however your code appears to be sorting all depths and I need "sortRoutine(@array, 2, 1, 4, 5) for example.

        I have an existing piece of code that has an array of arrays that needs to be sorted like this and Funk's code was sorting an array of refs.


Re^2: How would I sort a two-dimensional array by multiple columns?
by dbmathis (Scribe) on Mar 16, 2008 at 15:06 UTC

    Hi Funk, I like your solution and I am able to get it working fine in test, however in my existing code I will be passing a list of array references within an array to the routine (@unsorted).

    For example here's the part of my code where I am loading the array:

    while ( @row = $sth->fetchrow_array ) { push @x, [ @row ]; }
    $rindex = 0; $i = 1; do { foreach ( @columns ) { if ( $_ <= $qstart_column - 2 ) { $unsorted[$rindex][$_] = $x[$i][$_]; } else { $unsorted[$rindex][$_] = $x[$i][$_ - $nun_of_questions +]; } } $rindex += 1; $i += $nun_of_questions; } while ( $i <= $#x );

    Right now when run your code in my code I get the following:

    Use of reference "ARRAY(0x10b5810)" as array index at /home/dmathis/qw +est_qqs/transpose-qqs-dev line 367. Use of reference "ARRAY(0x10b5810)" as array index at /home/dmathis/qw +est_qqs/transpose-qqs-dev line 367. Use of uninitialized value in numeric comparison (<=>) at /home/dmathi +s/qwest_qqs/transpose-qqs-dev line 367. Use of uninitialized value in numeric comparison (<=>) at /home/dmathi +s/qwest_qqs/transpose-qqs-dev line 367. ................ ................ ................

    I just need to figure out what to alter in your code to handle my array.

    Best Regards