在前面的一个问题中,适航询问如何从数组中删除前5个元素:How do I remove the first five elements of an array?
在几项建议中,friedo提出了以下建议:
my $cnt = 0; @array = map { ++$cnt < 5 ? ( ) : $_ } @array;
我一点也不懂。请向我解释一下这件事是怎么回事,因为我没法把头挪开?
我知道三元钩子操作符的工作方式是这样的:(如果有的话)?(然后这样做):(否则就这样做)
例如:$a=2; print ($a==2 ? 3 : 4) #这个打印:3,因为我们有:($a==2 ?3: 4),意思是:(如果$a等于2)?(然后打印3):(否则打印4)
因此,使用friedo的代码,首先将$cnt增加到1,然后我们有:
$cnt < 5 ? ( ) : $_,意思是:if $cnt is less than 5 ? then ( ) : otherwise $_
我可以看到$_位是如何工作的,因为有时我会像这样使用map:
@array = map { $_, "\n" } @array
它从@array复制一个元素,将副本放置到$中,然后添加一个\n换行符,然后将$中的值复制回@array (它对@array中的所有值都这样做,因此基本上它会向@array中的每个元素添加换行符)
因此:
@array = map { if $cnt is less than 5 then ( ) otherwise $_ } @array
意思是:
@array = map { if $cnt is less than 5 then ( ) otherwise copy the element back to @array }
所以很明显()意思是‘摆脱它’,但我只是不知道它是如何工作的。请你解释一下好吗?
发布于 2011-02-27 18:03:28
在map中,数组中的每个项都被传递到代码块(在$_中),在代码块中可以将其转换为其他值。换句话说,map转换一个列表。
在这种情况下,我们希望丢弃计数($cnt)小于5的值。那么,当条件为真时,如何使map块返回"nothing“呢?
我们不能说
my $cnt = 0; @array = map { ++$cnt < 5 ? undef : $_ } @array;因为这样我们就会得到一个看起来像
( undef, undef, undef, undef, undef, 6, 7, 8 ... )这不是我们想要的。
但是返回( )将返回一个空列表。考虑到这些情况中的每一种情况下的push @foo, ( );或@bar = ( 1, 2, 3, ( ), 4, 5, 6 );,空的parens集是一个零项的列表,它不会对相关数组产生任何影响。
在需要返回列表项或根本不返回列表项的三元组中,空列表非常有用。强制在表达式上列出上下文以获得计数也很有用:
my $count = ( ) = $str =~ /\d/g;在这里,通过将正则表达式赋值给一个空列表,将regex放入列表上下文中,给出字符串中数字的计数。然后我们将空列表分配给$count。
在map中使用列表的另一个常见示例是,当您将某个内容转换为哈希时。例如,
my %unique = map { $_ => 1 } @duplicates;在这里,@duplicates中的每一项都被转换成一个类似于( 'foo' => 1 )的双元素列表,尽管这并不明显,因为不涉及父元素。然后,所有的两个项列表都被构建成一个大列表,其中包含了组成散列的交替键和值。假设您想要进行此散列,但不包括某些项。在这种情况下,我们要么需要返回键/值,要么什么都不需要。因此,这是一个使用空列表的好机会:
my %filtered_unique = map { some_test( $_ ) ? ( ) : ( $_ => 1 ) } @duplicates;发布于 2011-06-16 11:05:33
我知道我在这里有点晚了,但是为什么不做一些简单的事情呢?
我的@截断= @array5 5 .$#array
发布于 2011-02-27 18:05:39
显然,您可以返回一个列表而不是一个元素,并通过连接这些列表和元素来映射结果。()只是本例中的空列表。要了解更多信息,请复制粘贴示例,并将()替换为(1, 2, 3)。
https://stackoverflow.com/questions/5134823
复制相似问题