1

我试图弄清楚如何在 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();
4

1 回答 1

2

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

@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;
于 2013-08-09T14:32:09.177 回答