Is there an elegant zip to interleave two lists in Perl 5?
我最近在 Perl 5 中"需要"了一个 zip 函数(当时我正在考虑如何计算相对时间?),即一个函数,它接受两个列表并将它们"压缩"到一个列表中,交错元素。
(伪)示例:
1 2 3
| @a=(1, 2, 3);
@b=('apple', 'orange', 'grape');
zip @a, @b; # (1, 'apple', 2, 'orange', 3, 'grape'); |
Haskell 在 Prelude 中有 zip,而 Perl 6 有一个内置的 zip 运算符,但是如何在 Perl 5 中以优雅的方式做到这一点呢?
n
List::MoreUtils 模块有一个 zip/mesh 函数可以解决问题:
1 2 3 4 5 6
| use List::MoreUtils qw(zip);
my @numbers = (1, 2, 3);
my @fruit = ('apple', 'orange', 'grape');
my @zipped = zip @numbers, @fruit; |
这里是网格函数的来源:
1 2 3 4 5 6
| sub mesh (\\@\\@;\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@) {
my $max = -1;
$max $#$_ && ($max = $#$_) for @_;
map { my $ix = $_; map $_-[$ix], @_; } 0..$max;
} |
n
n
1 2 3 4
| my @l1 = qw/1 2 3/;
my @l2 = qw/7 8 9/;
my @out;
push @out, shift @l1, shift @l2 while ( @l1 || @l2 ); |
如果列表的长度不同,这会将 \\'undef\\' 放在额外的插槽中,但如果您不想这样做,您可以轻松解决此问题。像(@l1[0]
n
n
|