在Perl 5中是否有一个优雅的zip可以插入两个列表? [英] Is there an elegant zip to interleave two lists in Perl 5?

查看:69
本文介绍了在Perl 5中是否有一个优雅的zip可以插入两个列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在Perl 5中需要"一个zip函数(当时我正在考虑我该如何计算相对时间?),也就是说,该函数需要两个列表,然后将它们压缩"到一个列表中,从而对元素进行交织.

I recently "needed" a zip function in Perl 5 (while I was thinking about How do I calculate relative time?), i.e. a function that takes two lists and "zips" them together to one list, interleaving the elements.

(伪)示例:

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

Haskell压缩了Prelude

Haskell has zip in the Prelude and Perl 6 has a zip operator built in, but how do you do it in an elegant way in Perl 5?

推荐答案

假定您有两个列表,并且它们的长度完全相同,以下是最初由merlyn(Randal Schwartz)提出的解决方案,他称其为perly: /p>

Assuming you have exactly two lists and they are exactly the same length, here is a solution originally by merlyn (Randal Schwartz), who called it perversely perlish:

sub zip2 {
    my $p = @_ / 2; 
    return @_[ map { $_, $_ + $p } 0 .. $p - 1 ];
}

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

What happens here is that for a 10-element list, first, we find the pivot point in the middle, in this case 5, and save it in $p. Then we make a list of indices up to that point, in this case 0 1 2 3 4. Next we use map to pair each index with another index that’s at the same distance from the pivot point as the first index is from the start, giving us (in this case) 0 5 1 6 2 7 3 8 4 9. Then we take a slice from @_ using that as the list of indices. This means that if 'a', 'b', 'c', 1, 2, 3 is passed to zip2, it will return that list rearranged into 'a', 1, 'b', 2, 'c', 3.

这可以按照ysth的方式在单个表达式中编写,如下所示:

This can be written in a single expression along ysth’s lines like so:

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

您是否想使用这两种版本取决于您是否可以记住自己的工作方式,但是对我来说,这是一个扩展思维的方式.

Whether you’d want to use either variation depends on whether you can see yourself remembering how they work, but for me, it was a mind expander.

这篇关于在Perl 5中是否有一个优雅的zip可以插入两个列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆