Perl排序数组

时间:2013-08-09 14:24:20

标签: perl sorting

我试图弄清楚如何在Perl中对文件名列表进行排序。

每个文件都是PDF文件,我使用Perl的PDF :: Reuse

合并为单个pdf

每个pdf文件名都有两个唯一标识符。 1)是帐户ID& 2)报告类型。

示例:

C1234.lfs.pdf

C1234 =帐户ID lfs =报告类型。

每个帐户可能有多个报告需要按特定顺序排列。

如何指定报告类型的顺序?我想使用一个配置文件,其中脚本将查看在合并到1 pdf文件之前对每个帐户报告进行排序的顺序。 我希望的顺序是:

AcctId.lau.pdf AcctId.lsm.pdf AcctId.lad.pdf AcctId.lfs.pdf AcctId.lbe.pdf

@PDFS = (<*l*.pdf>);
@REVERSED_LIST = reverse(@PDFS);
prFile($OutPut);
for my $pdf (@REVERSED_LIST) {
    next if($pdf eq $OutPut);
    &Logit("Adding $pdf to $OutPut");
    prDoc($pdf);
}
prEnd();

很抱歉,如果我没有正确解释这一点,我们将不胜感激。

正在测试的新代码没有给出正确的顺序。

@PDFS = (<*l*.pdf>);
my %lsfOrder = (lua=>0, lsm=>1, lfw=>2);
@SORTED = map { $_->[0] } # Take just the original file name
     sort { 
        $a->[1] cmp $b->[1] ? 
          $a->[1] cmp $b->[1] : # compare by account id if different
          $lsfOrder{$a->[2]} <=> $lsfOrder{$b->[2]} 
      }
      map {
        [ $_, split('.', $_) ] # split into id/type once at the beginning
      } @PDFS;

prFile($OutPut);
for my $pdf (@SORTED) {
   next if($pdf eq $OutPut);
   &Logit("Adding $pdf to $OutPut");
   #print "Adding $pdf to $OutPut\n";
       prDoc($pdf);
}
    prEnd();

1 个答案:

答案 0 :(得分:2)

Perl sort将代码块作为可以控制排序的第一个参数。定义了两个特殊变量,'$ a'和'$ b',它们是要比较的两个元素。从那里,您将使用cmp<=>来比较字符串的不同部分,并返回a是否小于,大于或等于b。 sort函数根据列表中的内部排序算法选择$ a和$ b。 E.g:

@SORTED = sort {
  my @a = split ".", $a;
  my @b = split ".", $b;
  if ($a[0] cmp $b[0] != 0) { return $a[0] cmp $b[0] }
  my %lsfOrder = (lau=>0, lsm=>1, lad=>2, lfs=>3, lbe=>4);
  my $lsfA = $lsfOrder{$a[1]};
  my $lsfB = $lsfOrder{$b[1]};
  return $lsfA <=> $lsfB;
} @PDFS;

上面的代码将文件名拆分为'。'。然后它比较第一个元素(帐户ID),如果它们不相同,则返回该比较的结果。否则返回比较报告类型的结果。它按照你给出的顺序将lsf转换为整数,然后比较这些整数。

编辑:Joe Z对加速提出了很好的建议。总结一下:

my %lsfOrder = (lau=>0, lsm=>1, lad=>2, lfs=>3, lbe=>4);
@SORTED = map { $_->[0] } # Take just the original file name
          sort { 
            $a->[1] cmp $b->[1] ? 
              $a->[1] cmp $b->[1] : # compare by account id if different
              $lsfOrder{$a->[2]} <=> $lsfOrder{$b->[2]} # otherwise, compare by report type in specific order
          }
          map {
            [ $_, split('.', $_) ] # split into id/type once at the beginning
          } @PDFS;