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

Lit*_*rat 5 perl

在上一个问题中,seaworthy询问如何从数组中删除前5个元素:如何删除数组 的前五个元素?

在几个建议中,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 }

所以很明显()意味着"摆脱它",但我不确定它是如何工作的.请你解释一下吗?

fri*_*edo 10

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

在这种情况下,我们想要丢弃count($cnt)小于5的值.那么map当该条件为真时,如何使块返回"nothing"?

我们不能说

my $cnt = 0; @array = map { ++$cnt < 5 ? undef : $_ } @array;
Run Code Online (Sandbox Code Playgroud)

因为那时我们最终会得到一个看起来像的数组

( undef, undef, undef, undef, undef, 6, 7, 8 ... )
Run Code Online (Sandbox Code Playgroud)

这不是我们想要的.

但返回( )返回一个空列表.考虑push @foo, ( );@bar = ( 1, 2, 3, ( ), 4, 5, 6 );在每种情况下,空的parens集是一个零项列表,对相关的数组没有任何影响.

空列表在三元组中很有用,您需要返回列表项或根本不返回任何内容.强制列表上下文在表达式上获取计数也很有用:

my $count = ( ) = $str =~ /\d/g;
Run Code Online (Sandbox Code Playgroud)

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

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

my %unique = map { $_ => 1 } @duplicates;
Run Code Online (Sandbox Code Playgroud)

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

my %filtered_unique = map { some_test( $_ ) ? ( ) : ( $_ => 1 ) } @duplicates;
Run Code Online (Sandbox Code Playgroud)