Assuming you have exactly two lists and they are exactly the same length, here is a solution originally by merlyn (Randal Schwartz), who called it perversely perlish:
sub zip2 {
my $p = @_ / 2;
return @_[ map { $_, $_ + $p } 0 .. $p - 1 ];
}
What happens here is that for a 10-element list, first, we find the pivot point in the middle, in this case 5, and save it in $p
. Then we make a list of indices up to that point, in this case 0 1 2 3 4. Next we use map
to pair each index with another index that’s at the same distance from the pivot point as the first index is from the start, giving us (in this case) 0 5 1 6 2 7 3 8 4 9. Then we take a slice from @_
using that as the list of indices. This means that if 'a', 'b', 'c', 1, 2, 3
is passed to zip2
, it will return that list rearranged into 'a', 1, 'b', 2, 'c', 3
.
This can be written in a single expression along ysth’s lines like so:
sub zip2 { @_[map { $_, $_ + @_/2 } 0..(@_/2 - 1)] }
Whether you’d want to use either variation depends on whether you can see yourself remembering how they work, but for me, it was a mind expander.