my @array_of_references;
for my $line (<DATA>) {
my @values = split ' ', $line;
push @array_of_references, \@values; #The \ creates a reference.
}
my @sorted_refs = sort by_my_custom_func @array_of_references;
sub by_my_custom_func {
if ($a->[0] < $b->[0]) {return -1} # $a should come before $b
elsif ($a->[0] > $b->[0]) {return +1} # $a should come after $b
#Execution arrives here only if $a->[0] equals
#$b->[0]:
if ($a->[1] < $b->[1]) {return +1} # $a should come after $b
elsif ($a->[1] > $b->[1]) {return -1} # $a should come before $b
else {return 0}
}
for my $arr_ref (@sorted_refs){
print "@$arr_ref" . "\n";}
__DATA__
7 22
12 20
7 15
1 5
7 10
--output:--
1 5
7 22
7 15
7 10
12 20
perl's sort function can be a little hard to understand. As far as I can tell, the value you return from a custom sort function always determines what happens to $a. If you return a negative number, then $a will come before $b in the sorted results; and if you return a positive number then $a will come after $b in the sorted results.
Note that the <=> operator is just a shortcut for:
if ($a < $b) {return -1}
elseif ($a > $b) {return +1}
else {return 0}
However if you reverse the order of $a and $b, e.g. $b <=> $a, you get a reverse sort. That's because when sort calls the <=> operator, otherwise known as the "spaceship operator", sort calls it like this:
$a = 1;
$b = 2;
my $result1 = spaceship($a, $b);
print $result1 . "\n";
my $result2 = spaceship($b, $a);
print $result2 . "\n";
sub spaceship {
my $x = shift;
my $y = shift;
if ($x < $y) {return -1}
elsif ($x > $y) {return +1}
else {return 0};
}
--output:--
-1
1
Remember, sort() uses the return value from the sort function, in this case <=>, to determine what to do with $a. In the first case, $a <=> $b, the -1 tells sort() that $a should go before $b, and in the second case, $b <=> $a, the 1 tells sort() that $a goes after $b. In short, the <=> operator always thinks what is on its right is $a and what's on its left is $b. |