先普及下概念,看http://en.wikipedia.org/wiki/Schwartzian_transform 或者 看IntermediatePerl 中的9.4
在平时工作中,我们会经常接触到一些对文件内容做排序的工作。
像一般的升序排序,我会用sort命令来完成。
但是有些复杂的排序,比如,按第一列升序,再按第二列降序排,...等这种多级排序,我们就需要用到Schwartzian变换。
Schwartzian Transform基本格式如下,建议使用下列排版,如果写到一行,就很难看。
@sorted = map { $_->[0] }
sort { $a->[1] cmp $b->[1] }
map { [$_, foo($_)] }
@unsorted;
或者
@sorted = map $_->[0],
sort { $a->[1] cmp $b->[1] }
map [$_, foo($_)],
@unsorted;
扩展一下,如果有N级排序,可以写成
@sorted = map $_->[0],
sort { $a->[1] cmp $b->[1]
or $a->[2] cmp $b->[2]
... ...
or $a->[N] cmp $b->[N]}
map [$_, foo($_)],
@unsorted;
举例说明
我想将文本txt中的第一列按升序排列,当第一列数值相同时,第二列按降序排列,当第二列相同时,第三列按升序排列。txt内容如下
4 6 3
4 5 1
1 2 3
1 9 0
2 0 5
3 6 2
2 0 8
2 0 6
脚本如下
$cat sort.pl
#!/usr/bin/perl
my @sort_txt = map $_->[0],
sort {$a->[1] <=> $b->[1]
or $b->[2] <=> $a->[2]
or $a->[3] <=> $b->[3]}
map [$_, (split)], <>;
print @sort_txt;
$a->[N] <=> $b->[N] 就是升序排列
$b->[N] <=> $a->[N] 就是降序排列
$perl sort.pl txt
1 9 0
1 2 3
2 0 5
2 0 6
2 0 8
3 6 2
4 6 3
4 5 1