你可以通过使用 || 或者 or 操作符级连多个比较的方法进行额外层次的排序。这种方法相当漂亮,因为比较操作符通常在相等的时候返回 0,这样就令它们能落到下一个比较。下面,散列键字首先根据它们相关的销售额排序,然后在根据键字本身进行排序(以处理有两个或多个部门销售额相同的情况):
sub by_sales_then_dept {
$sales_amount{$b} <=> $sales_amount{$a}
||
$a cmp $b
}
for $dept (sort by_sales_then_dept keys %sale_amount) {
print "$dept => $sales_smount{$dept}\n";
}
假设 @recs 是一个散列引用的数组,而这里每个散列包含象 FIRSTNAME,LASTNAME,AGE,HEIGHT,和 SALARY 这样的域。下面的过程把那些记录中的人们按照下面的顺序排列:先是财富,然后是身高,然后是年龄(越小越靠前),最后是名字的字母顺序:
sub prospects {
$b->{SALARY} <=> $a->{SALARY}
||
$b->{HEIGHT} <=> $a->{HEIGHT}
||
$a->{AGE} <=> $b->{AGE}
||
$a->{LASTNAME} cmp $b->{LASTNAME}
||
$a->{FIRSTNAME} cmp $b->{FIRSTNAME}
}
@sorted = sort prospects @recs;
任何可以从 $a 和 $b 中得到的有用信息都可以在一个排序过程中比较的基础来用。比如,如果多行文本要根据特定域来排序,那么可以在排序过程中使用 split 以获取该域:
@sorted_lines = sort {
@a_fields = split /:/, $a; # 冒号分隔的域
@b_fields = split /:/, $b;
$a_fields[3] <=> $b_fields[3] # 对第四个域进行能够数字排序,然后
||
$a_fields[0] cmp $b_fields[0] # 对第一个域进行能够字串排序,然后
||
$b_fields[2] <=> $a_fields[2] # 对第而个域进行行能够数字反向排序
... # 等等
} @lines;
不过,因为 sort 使用给 $a 和 $b 的不同的数值对多次运行排序过程,所以前面的例子将会比对每一行都做多余的重新。
为了避免发生象为了比较数据域导致的多次的行带来的开销,我们可以在排序之前对每个值进行一次操作,然后把生成的信息保存起来。下面,我们创建了一个匿名数组以捕获每一行以及该行的结果:
@temp = map { [$_, split /:/] } @lines;
然后,我们对数组引用排序:
@temp = sort {
@a_fields = @$a[1..$#$a];
@b_fields = @$b[1..$#$b];
$a_fields[3] <=> $b_fields[3] # 对第四个域进行能够数字排序,然后
||
$a_fields[0] cmp $b_fields[0] # 对第一个域进行能够字串排序,然后
||
$b_fields[2] <=> $a_fields[2] # 对第而个域进行行能够数字反向排序
... # 等等
} @temp;
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-9.html
家用电器设计寿命一般是多少年
不行