码:
@all_matches = grep
{
! ( $seensentence
{
$_->[0] .'-'. $_->[1] .'-'. $_->[5]
}
++ )
}
@all_matches;
Run Code Online (Sandbox Code Playgroud)
目的:此代码从阵列中删除某些元素的重复项,@all_matches即AoA.
我完全崩溃的尝试(?? ?? ??我不确定的地方):
Grep返回@all_matches返回true 的元素.
哈希的关键%seensentence是三个元素?? 的@all_matches.由于散列只能有唯一键,所以第一次通过它的值从undef(0)递增到1.下一次,它是一个定义的值,但是!只有当它的undef(相关的唯一值)时,grep才会返回它用那个元素).
我的问题:
(1)如何{$_->[0] .'-'. $_->[1] .'-'. $_->[5]}++变成HoH?
我被告知这是实现它的另一种(惯用的)方式.在黑暗中刺伤将是:
( {$_->[0] => 0,
$_->[1] => 0,
$_->[5] => 0} )++
Run Code Online (Sandbox Code Playgroud)
(1b)因为我不明白原作是如何做我想要的.我读到的-bareword是相同的,"-bareword"所以我尝试过:{"$_->[0]" . "$_->[1]". "$_->[5]"}它看起来完全相同.我仍然不明白:它是将每个元素分别视为一个键(a)(如一个键数组)还是它(b)正确:所有同时(因为.将它们连接成一个字符串)或者是它(c) )不做我认为的事情?
(2)这是什么意思:$_->[0] || $_->[1] || $_->[5]?它与上面没有相同的做法.
我读到:短路逻辑运算符返回最后一个值,所以它会检查一个值,{$_->[0]}如果有一个,我认为那里的值会增加,如果没有它会检查下一个元素,直到没有为真,这是当grep传递唯一值时.
谢谢你的时间,我尽量尽可能彻底(出错?)但是如果有任何遗漏,请告诉我.
首先让我们把它grep变成一个foreach循环,这样我们就可以更清楚地检查它.为了清楚起见,我将把一些习语扩展为更大的构造.
my @all_matches = ( ... );
{
my %seen;
my @no_dupes;
foreach my $match ( @all_matches ) {
my $first_item = $match->[0];
my $second_item = $match->[1];
my $third_item = $match->[5];
my $key = join '-', $first_item, $second_item, $third_item;
if( not $seen{ $key }++ ) {
push @no_dupes, $match;
}
}
@all_matches = @no_dupes;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,原来的编码器创建使用$比赛举行的数组引用的哈希键,为每个所指指数$match->[0],1和5.由于散列键是唯一的,因此在推入之前检查密钥是否已存在,将删除任何重复项@no_dupes.
该grep{}机制只是一个更有效的代码(即,更快的类型,并没有一次性变量)成语来完成同样的事情.如果它有效,为什么要重构呢?你需要改进的是什么不做?
要对HoH做同样的事情,你可以这样做:
my @all_matches = ( ... );
{
my %seen;
my @no_dupes;
foreach my $match ( @all_matches ) {
my $first_item = $match->[0];
my $second_item = $match->[1];
my $third_item = $match->[5];
if( not $seen{ $first_item }->{ $second_item }->{ $third_item }++ ) {
push @no_dupes, $match;
}
}
@all_matches = @no_dupes;
}
Run Code Online (Sandbox Code Playgroud)
哪个可以翻译成grep如下:
my @all_matches = ( ... );
{
my %seen;
@all_matches = grep { not $seen{$_->[0]}->{$_->[1]}{$_->[5]}++ } @all_matches;
}
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,我没有看到构建数据结构的明显优势,除非您打算%seen稍后使用其他内容.
对于||操作员来说,这是一种不同的动物.我想不出在这种情况下使用它的任何有用方法.例如," $a || $b || $c" 的逻辑短路运算符测试布尔的真实性$a.如果是,则返回其值.如果它是假的,它会$b以同样的方式检查.如果它是假的,它会$c以同样的方式检查.但如果$a是真的,$b永远不会被检查.如果$b是真的,$c永远不会被检查.