Perl 提供了多种数组排序方法,以下是主要的几种:
1. 基本排序 - sort
# 默认按字符串顺序排序(ASCII)
my @sorted = sort @array;
# 示例
my @words = qw(banana apple cherry);
my @sorted_words = sort @words; # ('apple', 'banana', 'cherry')
2. 数值排序
# 使用比较运算符 <=> 进行数值排序
my @numbers = (10, 2, 45, 23, 1);
my @sorted_nums = sort {$a <=> $b} @numbers; # (1, 2, 10, 23, 45)
# 降序排列
my @desc_nums = sort {$b <=> $a} @numbers; # (45, 23, 10, 2, 1)
3. 复杂排序
# 按字符串长度排序
my @by_length = sort {length($a) <=> length($b)} @words;
# 不区分大小写排序
my @case_insensitive = sort {lc($a) cmp lc($b)} @words;
# 多条件排序
my @people = (
{name => 'Alice', age => 30},
{name => 'Bob', age => 25},
{name => 'Alice', age => 20}
);
my @sorted_people = sort {
$a->{name} cmp $b->{name} ||
$a->{age} <=> $b->{age}
} @people;
4. Schwartzian 变换
用于优化复杂排序性能:
# 原始方式(效率较低,多次计算)
my @sorted = sort {
some_expensive_function($a) cmp some_expensive_function($b)
} @array;
# Schwartzian 变换(缓存计算结果)
my @sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, some_expensive_function($_)] }
@array;
示例(按文件名后缀排序):
my @files = qw(file.txt image.png doc.pdf);
my @sorted_files = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, (split /\./)[-1]] }
@files;
5. Guttman-Rosler 变换
更高效的数值排序方法:
# 对于大量数值排序更高效
my @sorted = map { substr($_, 4) }
sort
map { sprintf("%08d", $_) . $_ }
@numbers;
6. 使用排序模块
use List::Util qw(shuffle);
use List::MoreUtils qw(nsort_by);
# 随机排序
my @shuffled = shuffle @array;
# 自然排序(如 file1.txt, file2.txt, file10.txt)
my @naturally_sorted = nsort_by { $_ } @files;
7. 原地排序
# 直接修改原数组
@array = sort @array; # 重新赋值
sort @array; # 错误!不会修改原数组
# 使用数组切片原地排序
@array[0..$#array] = sort @array;
8. 自定义排序子程序
sub custom_sort {
# 自定义比较逻辑
my ($x, $y) = @_;
return $y <=> $x; # 降序
}
my @sorted = sort custom_sort @numbers;
常用技巧总结
| 需求 |
Perl 代码 |
|---|
| 默认字符串排序 |
sort @array |
| 数值升序 |
sort {$a <=> $b} @array |
| 数值降序 |
sort {$b <=> $a} @array |
| 不区分大小写 |
sort {lc($a) cmp lc($b)} @array |
| 按长度排序 |
sort {length($a) <=> length($b)} @array |
| 多级排序 |
sort {$a->[0] cmp $b->[0] or $a->[1] <=> $b->[1]} @array |
| 随机排序 |
use List::Util qw(shuffle); shuffle @array |
注意事项
$a 和
$b 是特殊包变量,不需要声明
比较时返回 -1、0、1 分别表示小于、等于、大于
sort 默认是稳定排序(Perl 5.8+)
对于大数据集,考虑使用优化算法或模块
这些方法涵盖了 Perl 数组排序的基本和高级用法,可以根据具体需求选择合适的方法。