如何在 Perl 中按元素对数组求和?

发布于 2024-08-14 03:26:29 字数 201 浏览 5 评论 0原文

我有两个数组:

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );

我想对两个数组的项目进行求和以获得新的数组,例如

( 2, 1, 0, 1, 2 );

我可以在不循环数组的情况下做到这一点吗?

I have two arrays:

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );

I want to sum items of both arrays to get new one like

( 2, 1, 0, 1, 2 );

Can I do it without looping through arrays?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

浮华 2024-08-21 03:26:29

对于 Perl 5:

use List::MoreUtils 'pairwise';
@sum = pairwise { $a + $b } @arr1, @arr2;

for Perl 5:

use List::MoreUtils 'pairwise';
@sum = pairwise { $a + $b } @arr1, @arr2;
獨角戲 2024-08-21 03:26:29

如果您使用的是 Perl 6:

@a = (1 0 0 0 1) <<+>> (1 1 0 1 1)  #NB: the arrays need to be the same size

Perl 6 Advent日历有更多示例。

If you're using Perl 6:

@a = (1 0 0 0 1) <<+>> (1 1 0 1 1)  #NB: the arrays need to be the same size

The Perl 6 Advent Calendar has more examples.

揽清风入怀 2024-08-21 03:26:29

从根本上来说,不,如果不“循环遍历数组”就无法做到这一点,因为您需要访问两个数组的每个元素才能对它们求和。到目前为止,这两个答案都只是将循环隐藏在抽象层下,但它仍然存在。

如果您担心循环非常大的数组,最好考虑其他方法来保持总和最新。

Fundamentally, no, you can't do it without "looping through arrays" because you need to access every element of both arrays in order to sum them. Both the answers so far just hide the looping under a layer of abstraction but it's still there.

If you're concerned about looping over very large arrays, it's probably best to consider other ways of keeping the sum up-to-date as you go.

疯了 2024-08-21 03:26:29

循环数组有什么问题?这就是基本原理。

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
for ($i=0;$i<scalar @arr1;$i++){
    print $arr[$i] + $arr2[$i] ."\n";
}

what's wrong with looping over arrays? that's the fundamentals.

@arr1 = ( 1, 0, 0, 0, 1 );
@arr2 = ( 1, 1, 0, 1, 1 );
for ($i=0;$i<scalar @arr1;$i++){
    print $arr[$i] + $arr2[$i] ."\n";
}
寂寞花火° 2024-08-21 03:26:29

您已经了解了 C 风格的 for 循环和pairwise。这是一个惯用的 Perl for 循环和 map

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @for_loop;
for my $i ( 0..$#arr1 ) { 
    push @for_loop, $arr1[$i] + $arr2[$i];
}

my @map_array = map { $arr1[$_] + $arr2[$_] } 0..$#arr1;

我最喜欢 mappairwise。我不确定我对这两个选项是否有偏好。 pairwise 为您处理一些无聊的管道细节,但它不像 map 那样是内置的。另一方面,地图解决方案非常惯用,并且对于兼职 Perler 来说可能是不透明的。

因此,这两种方法都没有真正的胜利。 IMO,pairwisemap 都很好。

You've seen a C style for loop, and pairwise. Here's an idiomatic Perl for loop and map:

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @for_loop;
for my $i ( 0..$#arr1 ) { 
    push @for_loop, $arr1[$i] + $arr2[$i];
}

my @map_array = map { $arr1[$_] + $arr2[$_] } 0..$#arr1;

I like map and pairwise best. I'm not sure that I have a preference between those two options. pairwise handles some boring details of plumbing for you, but it is not a built-in like map. On the other hand, the map solution is very idiomatic, and may be opaque to a part-time perler.

So, no real wins for either approach. IMO, both pairwise and map are good.

南城追梦 2024-08-21 03:26:29

来自 http://www.perlmonks.org/?node_id=122393

@a = qw(1 2 3 4);
@b = qw(1 2 3 4);
@c = (); 

@c = map { $a[$_] + $b[$_] } ( 0 .. (@a > @b ? $#a : $#b) );

或:

$c[@c] = $a[@c] + $b[@c] while defined $a[@c] or defined $b[@c];

或:

$c[$_] = $a[$_] + $b[$_] for 0 .. (@a > @b ? $#a : $#b);

或(在 Perl 6 中):

@c = @a ^+ @b

From http://www.perlmonks.org/?node_id=122393

@a = qw(1 2 3 4);
@b = qw(1 2 3 4);
@c = (); 

@c = map { $a[$_] + $b[$_] } ( 0 .. (@a > @b ? $#a : $#b) );

Or:

$c[@c] = $a[@c] + $b[@c] while defined $a[@c] or defined $b[@c];

Or:

$c[$_] = $a[$_] + $b[$_] for 0 .. (@a > @b ? $#a : $#b);

Or (in Perl 6):

@c = @a ^+ @b
如梦亦如幻 2024-08-21 03:26:29

如果您真的害怕循环,那么您可以对数组进行二元切割,对对进行求和,然后递归地重新组装结果数组。那里没有循环,作为奖励,您可以了解快速傅立叶变换推导的一部分是如何工作的。

If you're really afraid of looping, then you can binary chop the arrays, sum the pairs, then recursively reassemble the resulting array. No looping there, and as a bonus you get to learn how part of the fast-fourier transform derivation works.

醉生梦死 2024-08-21 03:26:29

为了避免(显式)循环,这里有一个“替代”使用递归的解决方案:

#!/usr/bin/perl

use v5.20;

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @result=non_looping_pairwise_sum([ @arr1 ], [ @arr2 ]); # pass in copies, so the originals are not modified
say "@result";

sub non_looping_pairwise_sum { # only handles lists that have the same length
    my ($a1, $a2)=@_;

    return () if (scalar(@$a1)==0 and scalar(@$a2)==0);

    my $e1=shift @$a1;
    my $e2=shift @$a2;

    return ($e1+$e2, non_looping_pairwise_sum($a1, $a2));
}

输出:

2 1 0 1 2

请注意,use v5.20 意味着您不必编写 use strict;我认为使用警告。

向@parm 的想法致歉/表示敬意。

To avoid (explicit) looping, here is a solution that uses recursion "instead":

#!/usr/bin/perl

use v5.20;

my @arr1 = ( 1, 0, 0, 0, 1 );
my @arr2 = ( 1, 1, 0, 1, 1 );

my @result=non_looping_pairwise_sum([ @arr1 ], [ @arr2 ]); # pass in copies, so the originals are not modified
say "@result";

sub non_looping_pairwise_sum { # only handles lists that have the same length
    my ($a1, $a2)=@_;

    return () if (scalar(@$a1)==0 and scalar(@$a2)==0);

    my $e1=shift @$a1;
    my $e2=shift @$a2;

    return ($e1+$e2, non_looping_pairwise_sum($a1, $a2));
}

Output:

2 1 0 1 2

Note that use v5.20 means you don't have to write use strict; use warnings, I think.

Apologies/kudos to @parm for the idea.

蓦然回首 2024-08-21 03:26:29

我不确定一旦得到总和后你打算如何处理它,但你计划做更多的向量 y 类型的东西,那么 Math::Matrix 可能是一个不错的选择。

use Math::Matrix;

my $foo = Math::Matrix->new([ 1, 0, 0, 0, 1 ]);
my $bar = Math::Matrix->new([ 1, 1, 0, 1, 1 ]);
my $sum = $foo->add($bar);

I'm not sure what you plan to do with the sum once you have it, but you plan to do more vector-y type stuff, then Math::Matrix might be a good fit.

use Math::Matrix;

my $foo = Math::Matrix->new([ 1, 0, 0, 0, 1 ]);
my $bar = Math::Matrix->new([ 1, 1, 0, 1, 1 ]);
my $sum = $foo->add($bar);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文