Perl: Sort Matrix

By Xah Lee. Date: . Last updated: .

Here's a function that can sort a matrix in all possible ways.

This Perl version i wrote in 1999, and was used in production of a ecommerce server.

# -*- coding: utf-8 -*-
# perl

=pod

sort_matrix( $matrix, [[$n1, $stringQ, $directionQ], [$n2, $stringQ,
$directionQ], …]) sorts a matrix by $n1 th column then $n2 th…and
so on.

$matrix must be a reference to references of arrays, having the form
[[$e1, $e2,…], […], …].  $stringQ is a boolean indicating
whether to treat corresponding columns as a strings instead of as
number in the sorting process. True means string. $directionQ is a
boolean indicating ascending sort or not for the corresponding
column. In the column spec $n1 $n2 …, index counting starts at 0.

 Example:

 my $ref_matrix =
 [
   [3, 99, 'a'],
   [2, 77, 'a'],
   [1, 77, 'a']
 ];

sort_matrix( $ref_matrix,  [ [2,1,1], [1,0,1] ]);
# this means sort by third column, regarding it as strings, 
# and in ascending order. If tie, sort by second column, 
# regarding it as number, in ascending order.

# returns [[2,77,'a'],[1,77,'a'],[3,99,'a']];

=cut


sub sort_matrix($$) {
    my $ref_matrix = $_[0];
    my @indexMatrix = @{$_[1]};

    my @indexes = map {$_->[0]} @indexMatrix;
    my @operators = map {$_->[1] ? ' cmp ' : ' <=> '} @indexMatrix;
    my @directions = map {$_->[2]} @indexMatrix;

    my $body_code = '';
    my @body_array;
    for (my $i = 0; $i <= $#indexes; $i++) {
        if ($directions[$i]) {
            push(@body_array, "(\$a->[$i]" . $operators[$i]  . "\$b->[$i])");
        } else {
            push(@body_array, "(\$b->[$i]" . $operators[$i]  . "\$a->[$i])");
        };
    };
    $body_code = join( ' or ', @body_array);

    my $array_code = '(map { [' . join(q(, ), map {"\$_->[$_]"} @indexes) . ', $_]} @$ref_matrix)';

    my $code = "map {\$_->[-1]} (sort { $body_code} $array_code)";
    my @result = eval $code;
    return [@result];
};

If you have a question, put $5 at patreon and message me.

Perl

  1. Perl Overview
  2. Version String
  3. Help System

Detail

  1. Quoting String
  2. Format String
  3. String Operations
  4. True, False
  5. if then else
  6. Loop
  7. List / Array
  8. Loop Thru List
  9. Map f to List
  10. List Comprehension
  11. Hash Table
  12. Function Optional Param
  13. regex

Text Processing

  1. Unicode 🐪
  2. Convert File Encoding
  3. Read Write File
  4. Traverse Dir
  5. Find Replace
  6. Validate Local Links
  7. Split Line by Regex

Advanced

  1. Sort List, Matrix, Object
  2. Sort Matrix
  3. Sort Unstable
  4. Sort Misc
  5. List Modules, Search Paths
  6. Write a Module
  7. Complex Numbers
  8. System Call
  9. gzip
  10. Get Env Var
  11. GET Web Content
  12. Email