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

Hi, I would like to duplicate (or triplicate) every member of my array, how should I do? By instance, @array = (a,b,c,d), I want to obtain @array_final = (a,a,b,b,c,c,d,d) So in the end it would double (or triple) the number of member in my array. Thank you in advance!
  • Comment on How to duplicate every member of an array

Replies are listed 'Best First'.
Re: How to duplicate every member of an array
by LanX (Saint) on Jul 28, 2022 at 08:06 UTC
    Like this?

    @doubled = map { ($_) x 2 } @array

    edit

    FWIW, you could of course also do

    @doubled = (@array) x 2

    but the order would be different.

    a b c d a b c d

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Thanks! :)
Re: How to duplicate every member of an array
by Corion (Patriarch) on Jul 28, 2022 at 08:45 UTC

    Another alternative is to list each element twice explicitly in the map:

    @doubled = map { $_, $_ } @array

    Also, you can construct the new array in a loop instead of using map:

    my @doubled; for my $elt (@array) { push @doubled, $elt, $elt; }
      Thank you! :)
Re: How to duplicate every member of an array
by davido (Cardinal) on Jul 28, 2022 at 15:01 UTC

    List::Util is a core module (ships with Perl). It provides the mesh() function, which can be used as follows:

    my @doubled = mesh \@array, \@array;

    It turns out to be really quick.

    #!/usr/bin/env perl use v5.36; use strict; use warnings; use Benchmark qw(cmpthese); use List::Util qw(mesh); my @array = ('a' .. 'z'); cmpthese( -5, { mapped => \&mapped, meshed => \&meshed, }, ); sub mapped { return [map {$_,$_} @array]; } sub meshed { return [mesh \@array, \@array]; }

    The output:

    Rate mapped meshed mapped 111262/s -- -51% meshed 226692/s 104% --

    When I bump it up to 676 elements ('aa' .. 'zz'), the comparison is similar:

    Rate mapped meshed mapped 4157/s -- -50% meshed 8262/s 99% --

    With 11756 elements ('aaa' .. 'zzz') the ratio holds.


    Dave

Re: How to duplicate every member of an array
by AnomalousMonk (Archbishop) on Jul 28, 2022 at 09:34 UTC

    Note that the first method of LanX and Corion also works if assigning the doubled/tripled/etc. array directly back to the source array:

    Win8 Strawberry 5.8.9.5 (32) Thu 07/28/2022 5:30:16 C:\@Work\Perl\monks >perl use strict; use warnings; use Data::Dump qw(dd); my @ra = qw(a b c d); my $n = 3; @ra = map { ($_) x $n } @ra; dd \@ra; ^Z ["a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d", "d"]


    Give a man a fish:  <%-{-{-{-<

      Awesome, thank you! :)
Re: How to duplicate every member of an array
by hippo (Archbishop) on Jul 28, 2022 at 10:24 UTC

    You have some good answers from other Monks so now you can do this if you want.

    My question is: why do you want to do this? It will double/n-fold the memory footprint of your array for very little benefit. It sounds a little bit like an XY Problem. Would you care to elaborate?


    🦛

      ahah don't worry, this is to handle a very particular case in my script (not the general case, and hard to explain without context), so here it provides a fair solution to my problem, with a good benefit. But I understand your comment, since usually we want to do the opposite (get rid of the duplicates) ;)
      sounds like homework.
        ..if homework a oneliner is needed :D

        perl -MData::Dump -M"5;push @ARGV,reverse @ARGV" -e "push @m,shift,pop while @ARGV;dd @m" a b c

        ("a", "a", "b", "b", "c", "c")

        L*

        PS hello soblanc and welcome to the Monastery and to the wonderful world of Perl!

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.