Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
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 having an uproarious good time at the Monastery: (3)
As of 2024-04-19 21:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found