Perl: Sort Matrix
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.
=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]; };