perl方法:sort函数
www.diybl.com 时间:2008-02-24 作者:佚名 编辑:本站 点击: [评论]
-
-
] <=>; $b->;[1] }
map({ [$_, -M] } @filenames)
)
);
这个code结合用了map,sort分了好几层,记住偶以前提过的方法,从后往前看。map({ [$_, -M] } @filenames)返回一个列表,列表元素是匿名数组,匿名数组的第一个值是文件名,第二个值是文件的修改日期。
sort( { $a->;[1] <=>; $b->;[1] }...再对上述产生的匿名数组列表进行sort,它根据文件的修改日期进行sort。sort返回的结果是经过排序后的匿名数组。
最外围的map( { $_->;[0] }...就简单了,它从上述sort产生的匿名数组里提取出文件名。这个文件名就是根据修改日期进行sort过的呀,并且每个文件只运行了一次-M。
这就是著名的Schwartzian转换,这种用法在国外perl用户里很流行。记住仙子告诉你的Schwartzian概念哦,下次就不会被老外laugh at了,:p
本文作者说:
Orcish算法通常更难于编码,并且不如Schwartzian转换文雅。我推荐你使用Schwartzian转换作为可选择的方法。
也请记住基本的优化code的规则:(1)不写code;(2)在使code快速之前,先保证其正确;(3)在使code快速之前,先让它清楚。
10. 根据最后一列来对行进行sort(Schwartzian转换)
假如$str的值如下(每行以/n终结):
eir 11 9 2 6 3 1 1 81% 63% 13
oos 10 6 4 3 3 0 4 60% 70% 25
hrh 10 6 4 5 1 2 2 60% 70% 15
spp 10 6 4 3 3 1 3 60% 60% 14
按最后1个域的大小进行sort:
$str = join "/n",
map { $_->;[0] }
sort { $a->;[1] <=>; $b->;[1] }
map { [ $_, (split)[-1] ] }
split //n/, $str;
打印结果是:
eir 11 9 2 6 3 1 1 81% 63% 13
spp 10 6 4 3 3 1 3 60% 60% 14
hrh 10 6 4 5 1 2 2 60% 70% 15
oos 10 6 4 3 3 0 4 60% 70% 25
让我们从后往前,一步一步看上述code:
split //n/, $str; 这里返回一个列表,列表元素就是各个行了。
map { [ $_, (split)[-1] ] } 这里的map求得一个匿名数组列表,匿名数组的值分别是整行,和该行的最后一列。使用Schwartzian转换时,这步是关键哦,记着用map来构造你自己的匿名数组列表,匿名数组的第1个元素是最终需要的值,第2个元素是用于比较的值。
sort { $a->;[1] <=>; $b->;[1] } 对上1步中产生的匿名数组,按第2个元素进行sort,它返回sort后的匿名数组列表。
map { $_->;[0] } 对上1步中sort后的匿名数组,提取出第1个元素,也就是整行哦。
$str = join "/n", 把上步中的各行用"/n"连接起来,并赋值给$str。
也许你会说:“怎么这么麻烦呀?偶不想用这种方式。”那么,可用CPAN上的现成模块来代替:
use Sort::Fields;
@sorted = fieldsort [ 6, ''2n'', ''-3n'' ] @lines;
CPAN的模块文档很详细的,自己看看呀。
11. 重访高效sorting: Guttman-Rosler转换
考虑如下示例:
@dates = qw(2001/1/1 2001/07/04 1999/12/25);
你想按日期升序对它们进行排序,哪种方法最有效呢?
最直观的Schwartzian转换可以这样写:
@sorted = map { $_->;[0] }
sort { $a->;[1] <=>; $b->;[1]
or $a->;[2] <=>; $b->;[2]
or $a->;[3] <=>; $b->;[3]
}
map { [ $_, split m</>; $_, 3 ] } @dates;
然而,更高效的Guttman-Rosler转换(GRT)这样写:
@sorted = map { substr $_, 10 }
sort
map { m|(/d/d/d/d)/(/d+)/(/d+)|;
sprintf "%d-%02d-%02d%s", $1, $2, $3, $_
} @dates;
本文作者说:
GRT方法难于编码,并且比Schwartzian转换更难阅读,所以我推荐仅在极端环境下使用GRT。使用大的数据源,perl 5.005_03和linux 2.2.14进行测试,GRT比Schwartzian转换快1.7倍。用perl 5.005_02和windows NT 4.0 SP6进行测试,GRT比Schwartzian快2.5倍。
文章出处:DIY部落(file:///G:/我的桌面/perl方法:sort函数%20,web技术文章,FrontPage,网页设计.htm)