我有一个包含文件列表的数组.我想以一种方式对它进行排序,它会让我在数组的开头和之后的其余文件中包含.txt文件.
这就是我现在正在做的,这很好.
@files = (grep(/\.txt$/,@files),grep(!/\.txt$/,@files));
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?
bri*_*foy 10
您询问了有关为多个文件扩展名执行此操作的后续评论.在那种情况下,我将建立Schwartzian变换.如果您是ST的新手,我推荐Joseph Hall在Effective Perl Programming中的解释.虽然第二版很快就会推出,但我们基本上都没有解释,所以第一版也同样出色.谷歌图书似乎只显示第一版的每页一英寸,所以你在那里运气不好.
在这个答案中,我使用加权函数来决定哪些扩展应该移到顶部.如果扩展没有明确的权重,我只是用词典方式对它进行排序.您可以通过排序来愚弄以获得您想要的订单:
@files = qw(
buster.pdf
mimi.xls
roscoe.doc
buster.txt
mimi.txt
roscoe.txt
buster.rpm
mimi.rpm
);
my %weights = qw(
txt 10
rpm 9
);
my @sorted =
map { $_->{name} }
sort {
$b->{weight} <=> $a->{weight}
||
$a->{ext} cmp $b->{ext}
||
$a cmp $b
}
map {
my( $ext ) = /\.([^.]+)\z/;
{ # anonymous hash constructor
name => $_,
ext => $ext,
weight => $weights{$ext} || 0,
}
}
@files;
$" = "\n";
print "@sorted\n";
Run Code Online (Sandbox Code Playgroud)
my @sorted =
(
sort( grep /\.txt\z/, @files ),
sort( grep ! /\.txt\z/, @files )
);
Run Code Online (Sandbox Code Playgroud)
这里的诀窍是你正在对列表进行分区,然后独立地对每个分区进行排序.根据您的操作,这可能比尝试在一个排序操作中执行所有操作要好得多.相反,它可能并不总是更好.
还有其他各种方法可以完成这项工作,但它们并非如此简单.:)
这是我的MacBook Air与vanilla Perl 5.10.1的快速基准测试:
There are 600 files to sort
brian: 3 wallclock secs @ 369.75/s (n=1161)
control: 3 wallclock secs @ 1811.99/s (n=5744)
leon: 4 wallclock secs @ 146.98/s (n=463)
mobrule: 3 wallclock secs @ 101.57/s (n=324)
sort: 4 wallclock secs @ 559.62/s (n=1746)
Run Code Online (Sandbox Code Playgroud)
这是脚本:
use Benchmark;
use vars qw(@files);
@files = qw(
buster.pdf
mimi.xls
roscoe.doc
buster.txt
mimi.txt
roscoe.txt
) x 100;
printf "There are %d files to sort\n", scalar @files;
sub leon {
my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, !/\.txt$/ ]
} @files;
}
sub brian {
my @sorted =
(
sort( grep /\.txt\z/, @files ),
sort( grep ! /\.txt\z/, @files )
);
}
sub mobrule {
my @sorted =
sort { ($b=~/\.txt\z/) <=> ($a=~/\.txt\z/) || $a cmp $b }
@files;
}
sub plain_sort {
my @sorted = sort @files;
}
sub control {
my @sorted = @files;
}
timethese( -3,
{
brian => \&brian,
leon => \&leon,
mobrule => \&mobrule,
control => \&control,
sort => \&plain_sort,
}
);
Run Code Online (Sandbox Code Playgroud)
@sorted = sort { $b=~/\.txt$/ <=> $a=~/\.txt$/ || $a cmp $b } @files
Run Code Online (Sandbox Code Playgroud)
将首先放置.txt文件,然后按字典顺序排序(按字母顺序).
@sorted = sort { $b=~/\.txt$/ <=> $a=~/\.txt$/ } @files
Run Code Online (Sandbox Code Playgroud)
会先将.txt文件否则保留原来的顺序(sort是稳定的,因为Perl的5.8)