2

我只是想知道这是否可能:

use Modern::Perl;

my @list = ('a' .. 'j');

map { func($_) } each(@list);

sub func {
  my ($index, $value) = @_;
  say "$index => $value";
}
4

5 回答 5

8

不,你不能,因为each每次调用它都会返回一个键/值对。您只调用它一次,因此它将传递(0, $list[0])map,并且将为每个值调用一次子例程。

如果你想func用每个键/值对调用你可以写

map { func($_, $list[$_]) } keys @list;

但这是滥用map,因为它旨在将一个列表映射到另一个列表。你应该for像这样使用

func($_, $list[$_]) for keys @list;

你也可以each这样使用

my ($i, $v);
func($i, $v) while ($i, $v) = each @list;
于 2012-06-12T22:04:01.847 回答
3

最直接的方法是:

func($_, $a[$_]) for 0..$#a;
于 2012-06-13T02:09:31.070 回答
2

在列表上下文中,each @array返回一个包含两个元素的列表——一个数组索引和该索引处的数组元素的值。打电话

map { ... } each @array

因此就像

($index,$value) = each @array;
map { ... } ($index,$value);

这可能不是你想要的。如果func应该采用索引参数和值参数,那么也许你想做类似的事情

map { func($_, $list[$_]) } 0 .. $#list;
于 2012-06-12T22:08:56.860 回答
0

只需使用for

for ( my $index = 0; $index < scalar @list; $index++ ){
   my $value = $list[$index];
   say "$index => $value";
}
于 2012-06-12T21:54:00.127 回答
0

您将map其视为循环,丢弃返回值。在这种情况下,您不妨使用循环。但是,您不能将each @list其用作这样的循环条件,因为它不会扩展为完整列表。来自perldoc -f each

在列表上下文中调用时,返回一个 2 元素列表,其中包含哈希的下一个元素的键和值,或者数组的下一个元素的索引和值,以便您可以对其进行迭代。

此外,您只向子例程传递了一个值,而不是两者。您的each语句扩展为两个元素的列表,即数组的下一个索引和元素。但map每次迭代只需要其中一个。所以你得到输出:

Use of uninitialized value $value in concatenation...
0 =>
Use of uninitialized value $value in concatenation...
a =>

你可能想要的是这样的:

func($_) for keys @list;

sub func {
    my $index = shift;
    say "$index => $list[$index]";
}

keys可以以这种方式用于获取数组的索引。

于 2012-06-12T22:03:18.883 回答