是否有一个优雅的拉链交织在Perl 5的两个列表?

我最近“需要”一个zip函数在Perl 5(而我正在考虑大约 How do I calculate relative time?),即一个函数,需要两个列表和“拉链”他们在一起列表,交织元素。

(伪)示例:

@a=(1,2,3);
@b=('apple','orange','grape');
zip @a,@b; # (1,'apple',3,'grape');

Haskell has zip in the PreludePerl 6 has a zip operator内置,但是你如何在Perl 5中以优雅的方式做呢?

解决方法

假设你有两个列表,它们的长度完全相同,这里是一个由merlyn(Randal Schwartz)最初的解决方案,他将其称为periter:
sub zip2 {
    my $p = @_ / 2; 
    return @_[ map { $_,$_ + $p } 0 .. $p - 1 ];
}

这里发生的是,对于10个元素的列表,首先,我们找到中间的枢轴点,在这种情况下为5,并将其保存在$ p。然后我们创建一个索引列表到这一点,在这种情况下0 1 2 3 4.接下来我们使用map将每个索引与另一个索引配对与枢轴点相同的距离,因为第一个索引是从开始,给我们(在这种情况下)0 5 1 6 2 7 3 8 4 9.然后我们从@_使用一个切片作为索引列表。这意味着如果将’a’,’b’,’c’,1,2,3传递给zip2,它将返回重新排列为’a’,1,’b’,2,’c’,3 。

这可以写在ysth的单行表达式像这样:

sub zip2 { @_[map { $_,$_ + @_/2 } 0..(@_/2 - 1)] }

是否要使用这两种变体取决于你是否能够看到自己记住它们是如何工作的,但对我来说,这是一个思维扩展器。

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...