Perl 6单行打印文件的唯一行

问题描述 投票:1回答:2

我发现这个非常有用的单行,它可以工作,但我无法理解它是如何设法循环两次文件的行。

perl6 -ne 'state %l; .say if ++%l{$_} == 1' input-file.txt
perl6
2个回答
3
投票

只有一个周期。 它将所有行收集为%l中的键,其值是它看到它的次数。 如果这是第一次(… == 1)它遇到了当前行的副本,则会打印出来。

它基本上与以下相同:

my %l;

for $*ARGFILES.lines() {  # this is basically what `-n` does

  ++%l{ $_ };             # update the count

  .say if %l{ $_ } == 1;  # print it if this is the first time it was seen

}

我认为使用… if ++$… == 1代替… unless $…++的原因是&prefix:«++»&postfix:«++»略高性能


另一种可能更有效(取决于.unique的实现)的方式来写它:

perl6 -e '.put for $*ARGFILES.lines.unique' input-file.txt

2
投票

让我们解开这个有点。 -n选项在代码周围添加了一个for lines() { ... }循环,所以我们有

for lines() { 
    state %l;
    .say if ++%l{$_} == 1
}

为什么state var?没有简单的方法可以在该行的隐式循环的外部作用域中声明变量。否则你会把它写成

my %l;
for lines() { 
    .say if ++%l{$_} == 1
}

%l记录了一条线(存储在$_中)的次数。它使用自动验证,因此第一次看到一行时,++运算符会自动将其添加到散列中。

.say$_.say的简写

© www.soinside.com 2019 - 2024. All rights reserved.