perl结合地图和每个

时间:2012-06-12 21:47:05

标签: perl

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

use Modern::Perl;

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

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

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

5 个答案:

答案 0 :(得分:7)

不,你不能,因为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;

答案 1 :(得分:1)

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

map { ... } each @array
因此

就像

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

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

map { func($_, $list[$_]) } 0 .. $#list;

答案 2 :(得分:1)

最直接的方法是:

func($_, $a[$_]) for 0..$#a;

但如果你想要的话,还有:

use List::MoreUtils qw( pairwise );

pairwise { func($a, $b) }
   @{[ keys   @a ]},
   @{[ values @a ]};

答案 3 :(得分:0)

只需使用for

for ( my $index = 0; $index < scalar @list; $index++ ){
   my $value = $list[$index];
   say "$index => $value";
}

答案 4 :(得分: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来获取数组的索引。