【发布时间】:2011-08-05 11:37:39
【问题描述】:
我在 Perl 中有这样的代码:
#!/usr/bin/perl -w
my @a = ('one', 'two', 'three');
my @b = (1, 2, 3);
我想看到这个结果:@c = ('one1', 'two2', 'three3');
有没有办法可以将这些列表合并为一个?
【问题讨论】:
我在 Perl 中有这样的代码:
#!/usr/bin/perl -w
my @a = ('one', 'two', 'three');
my @b = (1, 2, 3);
我想看到这个结果:@c = ('one1', 'two2', 'three3');
有没有办法可以将这些列表合并为一个?
【问题讨论】:
假设你可以保证两个数组的长度总是相同的。
my @c = map { "$a[$_]$b[$_]" } 0 .. $#a;
【讨论】:
作为替代方案,您可以使用List::MoreUtils 中的pairwise:
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils qw( pairwise );
my @a = ( 'one', 'two', 'three' );
my @b = ( 1, 2, 3 );
my @c = do {
no warnings 'once';
pairwise { "$a$b" } @a, @b;
};
【讨论】:
$a 和$b——无论如何,你是在全局范围内声明它们。即使将它们本地化也没有多大意义。
once警告。
do 构造中对其进行伪本地化。在do 中做no warnings 'once' 更有意义。
List::MoreUtils 不是标准 Perl。
# avoid once warning 的无关代码进行比较。也就是说,我写过这样的代码,而且我经常觉得我需要对其进行评论。之后我想,如果我不想要警告,就说我不想要它。你知道,这很有趣:我反对 Damian 反对 PBP 中的 tie-s,但自从我读了这本书后,我还没有写过完整的代码。
为了完整起见,为了让 Tom 开心,这里是一个纯 perl 实现的 pairwise,您可以使用它:
use B ();
use List::Util 'min';
sub pairwise (&\@\@) {
my ($code, $xs, $ys) = @_;
my ($a, $b) = do {
my $caller = B::svref_2object($code)->STASH->NAME;
no strict 'refs';
map \*{$caller.'::'.$_} => qw(a b);
};
map {
local *$a = \$$xs[$_];
local *$b = \$$ys[$_];
$code->()
} 0 .. min $#$xs, $#$ys
}
由于这有点复杂,所以像 davorg 所示,使用 map 可能更容易。
【讨论】: