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

My question is very simple. I've often got 2 arrays which need to be combined into one, with the elements in each pairing with each other (as shown below). Is there a better way of doing this, or is this map/shift combination sensible?
@a = ('a','b','c'); @b = ('1','2','3'); #we want ('a-1','b-2','c-3') @a = map{$_="$_-".shift@b}@a; print "@a";

Replies are listed 'Best First'.
Re: Combining Arrays
by srawls (Friar) on May 20, 2001 at 19:18 UTC
    Well, I think you've got the right idea, but there is no need to do that asignment inside map. Try this (which is basically your code without the asignment):
    @a = map {"$_-" . shift @b } @a;


    The 15 year old, freshman programmer,
    Stephen Rawls
Re: Combining Arrays
by kschwab (Vicar) on May 20, 2001 at 19:15 UTC
    That seems reasonable to me. There's always more than one way to do it.

    Here's the more traditional version of yours:

    for (0..$#a) { $a[$_] = $a[$_] . "-" . shift(@b); }
    Update: I see now I missed the redundant $_ assignment in the original node. Too bad whoever -- this didn't help me out with an explanation :)
Re: Combining Arrays
by premchai21 (Curate) on May 20, 2001 at 20:32 UTC
    More ways of doing this:
    @c = map { "$a[$_]-$b[$_]" } (0..(($#a > $#b) ? $#a : $#b)); # And a more twisty way... my $iterator; { my $i = 0; $iterator = sub { ($i = 0, return undef) if (@_); return undef if ($i > $#a and $i > $#b); return ("$a[$i]-$b[$i]",$i++)[0]; }; } push @c, $_ while ($_ = $iterator->());
Re: Combining Arrays
by davorg (Chancellor) on May 21, 2001 at 15:33 UTC

    I think I'd do something like this (assuming that we know the arrays are the same length):

    @a = map { "$a[$_]-$b[$_]" } 0 .. $#a;
    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: Combining Arrays
by jeroenes (Priest) on May 21, 2001 at 15:49 UTC
    You can also transform it into a more general problem:

    Combine n arrays in an item-by-item way

    To do so, we just push all the arrays in a $AoA, and use boo_radley's transpose AoA and HTML table AoA contents. to transpose that $AoA, and take a simple map join( '-', @$_), @$_; to join the elements. Works for arbitrary n.

    Jeroen
    "We are not alone"(FZ)

(tye)Re: Combining Arrays
by tye (Sage) on May 21, 2001 at 19:58 UTC
      Just what i was looking for - perfect!
Re: Combining Arrays
by Big Willy (Scribe) on May 21, 2001 at 06:22 UTC
    This is simple, but your solutions is as good as any really:
    foreach (0 .. @a.""-1) { $a[$_] = $a[$_] . '-' . $b[$_]; }