9

我用了

Use List::MoreUtils qw(each_array);
my $it = each_array( @input_dump_arr, @created_dump_arr);
while ( my ($first, $second) = $it->()) {
}

这可以在默认的 perl 配置中工作吗?一个更广泛的问题是是否有编写“便携式”perl 脚本的指南?我是 Perl 的新手,只是想弄清楚 cpan 是否实际上类似于 boost 库对 c++ 的作用。

4

3 回答 3

7

它不是一个核心模块(意味着它没有与 perl 捆绑在一起),但它是一个相对常见的模块。我会毫不犹豫地使用它。

如果您真的很偏执,它可能不可用,假设数组的大小相同,您可以使用以下内容:

for my $i (0 .. $#array1) {
  my $first  = $array1[$i];
  my $second = $array2[$i];
}

不过好在 each_array() 是用纯 perl 实现的,所以你也可以查看 List/MoreUtils.pm 的源代码并复制粘贴相关的子程序。

于 2013-04-15T21:12:14.250 回答
4

您可能希望使用这种更简单的模块each_arrayref功能重写。each_array是这个函数的多余包装器,它使用原型来引用作为参数传递的数组。

它的功能与模块版本相同,只是它不检查它接收到的参数,并且返回的迭代器不检查它是否没有参数或'index'.

use strict;
use warnings;

sub each_array {

  my @copy = @_;
  my $i;
  my $max;

  for (map scalar @$_, @copy) {
    $max = $_ unless defined $max and $max > $_;
  }

  sub {
    return $i if @_ and shift eq 'index';
    my $new_i = defined $i ? $i + 1 : 0;
    return if $new_i >= $max;
    $i = $new_i;
    return map $_->[$i], @copy;
  }
}

my @array1 = qw/ A B C /;
my @array2 = qw/ D E F G /;

my $iter = each_array(\@array1, \@array2);

while (my @values = $iter->()) {
  printf "%d: %s\n", $iter->('index'), join ', ', map $_ // 'undef', @values;
}

输出

0: A, D
1: B, E
2: C, F
3: undef, G

当然,您可以简单地each_arrayrefList::MoreUtils模块中获取代码。它是独立的,将保证与您现有代码的兼容性。

于 2013-04-16T05:58:46.983 回答
2

有一些模块直接与 Perl 本身一起分发。它们通常被称为“核心模块”。你总是可以使用这些。List::Util是其中之一,但List::MoreUtils不是。

但是,是CPANList::MoreUtils上可用的模块。CPAN 通常被认为是“Perl 的标准库”,类似于 C++ 的“标准库”。大多数人认为要求他们的应用程序的用户从 CPAN 安装某些模块是可以的,特别是如果它们是使用良好的模块。

List::MoreUtils绝对是一个很好用的模块。它已经存在了一段时间。我所知道的所有主要 Linux 发行版都包含它的打包版本。

因此,如果您的目标不是 100% 独立于非核心模块,那么我强烈建议您继续使用List::MoreUtilsCPAN 上提供的大多数其他优质模块。这就是 Perl 摇滚的原因。

有点题外话:我不得不承认我更喜欢pairwise(也来自List::MoreUtils)恰好两个数组,因为它的行为更像map. 对于您的示例:

use List::MoreUtils qw(pairwise);
pairwise { do_stuff($a, $b) } @input_dump_arr, @created_dump_arr;
于 2013-04-15T20:57:28.553 回答