Wally
Wally

Reputation: 137

Trying to Use Perl to Join Two Arrays at each Element

I want to join two arrays together at the same element. For example, I want to combine $array1[0] and $array2[0] and so on down the road.

@array1 = qw(A B C D)
@array2 = qw(a b c d)

@array3 = qw(A a B b C c D d)

I tried previously to use an embedded loop, but that just produced the wrong output.

foreach my $liginfo_data_var (@liginfo_data)
{
    foreach my $ligands_data_var (@ligands_data)
    {
        print COMBLIG join ($liginfo_data_var, "\t", $ligands_data_var, "\n");

    }
}

I haven't been able to find an answer yet on StackOverflow and would hope to hear some suggestions. Many thanks!

Upvotes: 1

Views: 3170

Answers (2)

ThisSuitIsBlackNot
ThisSuitIsBlackNot

Reputation: 24063

Here's an example straight out of the documentation for List::MoreUtils:

use List::MoreUtils 'pairwise';

@a = qw/a b c/;
@b = qw/1 2 3/;
@x = pairwise { ($a, $b) } @a, @b;  # returns a, 1, b, 2, c, 3

EDIT: As ikegami pointed out, zip is a better solution:

use List::MoreUtils 'zip';

@a = qw/a b c/;
@b = qw/1 2 3/;
@x = zip @a, @b;  # returns a, 1, b, 2, c, 3

I ran a benchmark comparing zip, pairwise, and amon's map solution, all of which return a new array. pairwise was the hands-down loser:

             Rate pairwise      map      zip
pairwise 111982/s       --     -43%     -52%
map      196850/s      76%       --     -16%
zip      235294/s     110%      20%       --

Upvotes: 2

amon
amon

Reputation: 57600

(Aah, how easy this would be in Perl6: @array3 = @array1 Z @array2)

Do not iterate over the elements directly. Instead, loop over the indices of both arrays in parallel:

for my $i ( 0 .. $#array1 ) {
  push @array3, $array1[$i], $array2[$i];
}

Or with map: @array3 = map { $array1[$_], $array2[$_] } 0 .. $#array1.

This works fine if both input arrays have the same length. You can also use List::MoreUtils 'zip': @array3 = zip @array1, @array2.

But it seems you don't want to create an @array3. If you just want to print out both elements:

for my $i ( 0 .. $#array1 ) {
  say COMBLIG $array1[$i], "\t", $array2[$i];
}

Notice that I don't have to use join. That function concatenates an input list with a certain separator, which is given as fist argument. E.g. join ', ', 1..3 produces "1, 2, 3".

Upvotes: 7

Related Questions