当前位置:  开发笔记 > 编程语言 > 正文

是否有一个优雅的拉链来交错Perl 5中的两个列表?

如何解决《是否有一个优雅的拉链来交错Perl5中的两个列表?》经验,为你挑选了4个好方法。

我最近在Perl 5中"需要"一个zip函数(当时我正在考虑如何计算相对时间?),即一个函数,它将两个列表和"拉链"一起放到一个列表中,交错元素.

(伪)例如:

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

哈斯克尔在前奏拉链和Perl 6的有一个拉链运营商内置的,但你怎么做它在Perl 5优雅的方式?



1> Aristotle Pa..:

假设你有两个列表并且它们的长度完全相同,这里有一个最初由merlyn(Randal Schwartz)提出的解决方案,它称之为per per per per per:

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)] }

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



2> Jason Navarr..:

该列表:: MoreUtils模块有一个拉链/网格功能应该做的伎俩:

use List::MoreUtils qw(zip);

my @numbers = (1, 2, 3);
my @fruit = ('apple', 'orange', 'grape');

my @zipped = zip @numbers, @fruit;

这是网格函数的来源:

sub mesh (\@\@;\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@\@) {
    my $max = -1;
    $max < $#$_  &&  ($max = $#$_)  for @_;

    map { my $ix = $_; map $_->[$ix], @_; } 0..$max; 
}


什么是逃脱的标志?
@Roberto,不,但这只是一个原型黑客,你的眼睛因为所有错误的原因而流血.

3> Frank..:

我发现以下解决方案简单易读:

@a = (1, 2, 3);
@b = ('apple', 'orange', 'grape');
@zipped = map {($a[$_], $b[$_])} (0 .. $#a);

我相信它也比首先以错误的顺序创建数组然后使用切片重新排序的解决方案或修改@a和解决方案的解决方案更快@b.



4> jmcnamara..:

对于相同长度的数组:

my @zipped = ( @a, @b )[ map { $_, $_ + @a } ( 0 .. $#a ) ];


这对于不等大小的阵列存在问题.
推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有