Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Parallel processing two arrays with different numbers of elements

by ww (Archbishop)
on Sep 14, 2013 at 21:04 UTC ( [id://1054136]=perlquestion: print w/replies, xml ) Need Help??

ww has asked for the wisdom of the Perl Monks concerning the following question:

Just noodling around and -- Shazam! lightening struck (or maybe it was just that the dim bulb went on) --
but every time I have to process two arrays of differing lengths, in parallel, I have to go hunting for instructions or code-to-cargo-cult and maybe also for those remnants of hair I've just extracted trying to recall a decent approach.

So, does the algorithm implemented in the following code have an accepted name? or is it so dumb, it's known for the forcefulness with which it's been critiqued/criticized (and if so, why)? ...or (by some unlikely chance) novel?

#!/usr/bin/perl use 5.016; use warnings; # Parallel processing of two arrays with different numbers of elements my @arr=qw/a b c d e/; my @bar = qw/12 34 56/; my $i = 0; while ($i<($#arr+2)) { no warnings 'uninitialized'; say "\t \$i: $i"; say "\t\t $arr[$i], $bar[$i]"; ++$i; }

Execution:

C:\>D:\_Perl_\PMonks\parallelArrayProcess.pl $i: 0 a, 12 $i: 1 b, 34 $i: 2 c, 56 $i: 3 d, $i: 4 e, $i: 5 , C:\>

Replies are listed 'Best First'.
Re: Parallel processing two arrays with different numbers of elements
by tobyink (Canon) on Sep 14, 2013 at 21:10 UTC

    I call it "List::MoreUtils::pairwise".

    use v5.12; use List::MoreUtils; my @arr = qw/a b c d e/; my @bar = qw/12 34 56/; my $i = 0; List::MoreUtils::pairwise { say "\t$i"; say "\t\t$a, $b"; $i++; } @arr, @bar;
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      > I call it "List::MoreUtils::pairwise".

      unfortunately not a perfect solution :(

      using literal list is cumbersome

      DB<260> pairwise { $a => $b } @a, @{[a..d]} => (1, "a", 2, "b", 3, "c", 4, "d")

      no warning if $a or $b is lexical

      DB<261> my $a;pairwise { $a => $b } @a, @{[a..d]} => (undef, "a", undef, "b", undef, "c", undef, "d")

      sort does it right

      DB<262> my $a; sort {$a <=>$b} reverse 1..10;; Can't use "my $a" in sort comparison at (eval 360)[multi_perl5db.pl:64 +4] line 2.

      and there is no easy way to limit size to one of the arrays like with Hyper-Operators in Perl 6

      (update)

      @a »+« @b; # @a and @b MUST be the same size @a «+« @b; # @a can be smaller, will upgrade @a »+» @b; # @b can be smaller, will upgrade @a «+» @b; # Either can be smaller, Perl will Do What You Mean

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        For literal lists, I'd probably bypass the prototype:

        &pairwise( sub { $a => $b }, \@a, ['a'..'d'], );

        Or if you need to do it a lot, maybe wrap it with a different prototype:

        sub ref_pairwise (&;@) { goto \&List::Util::pairwise } ref_pairwise { $a + $b } \@a, ['a'..'d'];

        Limiting to the size of the arrays needs to be added explicitly to the block, but isn't especially challenging:

        use v5.12; use List::MoreUtils; my @arr = qw/a b c d e/; my @bar = qw/12 34 56/; my $i = 0; List::MoreUtils::pairwise { return if $i > $#arr || $i > $#bar; say "\t$i"; say "\t\t$a, $b"; $i++; } @arr, @bar;

        (It would be more sugary if that return could be a last, but ho hum.)

        use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: Parallel processing two arrays with different numbers of elements
by farang (Chaplain) on Sep 15, 2013 at 00:56 UTC

    Another possibility, using defined or instead of disabling warnings.

    use v5.16; use warnings; my @arr=qw/a b c d e/; my @bar = qw/12 34 56/; my $i = 0; while ($i<($#arr+2)) { say "\t \$i: $i"; say "\t\t ", $arr[$i] // q{}, ", ", $bar[$i] // q{}; ++$i; }

Re: Parallel processing two arrays with different numbers of elements
by Random_Walk (Prior) on Sep 14, 2013 at 21:51 UTC

    I would go with something like this

    #!/usr/bin/perl use strict; use warnings; use 5.14.0; my @a1 = qw (a b d e f g); my @a2 = qw (1 2 3 4 5 6 7); my $i = 0; my $count = $#a1 > $#a2 ? $#a1 : $#a2; for (0 .. $count) { no warnings 'uninitialized'; say "$_: $a1[$_] - $a2[$_]"; }

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1054136]
Approved by tobyink
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2024-03-28 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found