这是如何工作的:地图与三元钩子算子和()一起使用

时间:2011-02-27 17:53:46

标签: perl

在上一个问题中,seaworthy询问如何从数组中删除前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) #the print:3 因为我们有:($ a == 2?3:4) 这意味着:(如果$ a等于2)? (然后打印3):(否则打印4)

所以使用friedo的代码,首先$ cnt增加到1,然后我们有:

$cnt < 5 ? ( ) : $_ 意思是: if $cnt is less than 5 ? then ( ) : otherwise $_

我可以看到$ _位是如何工作的,因为我有时会使用这样的地图:

@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 }

如此清楚()意味着“摆脱它”之类的东西 但我只是不确定它是如何工作的。请你解释一下吗?

3 个答案:

答案 0 :(得分:10)

map中,数组中的每个项都被传递到代码块(在$_中),在那里它可以转换为其他值。换句话说,map会转换列表。

在这种情况下,我们想要丢弃count($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;

这里,我们将正则表达式放在列表上下文中,方法是将其分配给一个空列表,给出字符串中的数字位数。然后我们将该空列表分配给$count

map中使用列表的另一个常见示例是当您将某些内容转换为哈希时。例如,

my %unique = map { $_ => 1 } @duplicates;

此处@duplicates中的每个单项都会转换为一个看起来像( 'foo' => 1 )的双元素列表,尽管由于没有涉及到parens,因此它并不那么明显。然后,所有两项列表都构建成一个交替键和值的大列表,构成哈希。假设你想制作这个哈希但是排除了一些项目。在这种情况下,我们需要返回一个键/值,或者 nothing 。所以这是一个使用空列表的好机会:

my %filtered_unique = map { some_test( $_ ) ? ( ) : ( $_ => 1 ) } @duplicates;

答案 1 :(得分:2)

我知道我在游戏中有点晚了,但为什么不做一些简单的事情?

我的@truncated = @array [5 .. $#array]

答案 2 :(得分:1)

显然你可以返回一个列表而不是一个元素,map通过连接这些列表和元素来构造结果。在这种情况下,()只是空列表。要获得更多信息,请复制粘贴示例,然后将()替换为(1, 2, 3)