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

Dear Masters,
Suppose I have this array
my @elems = ("x", "y", "z"); # array size may be varied (lesser or more than 3)
Now I want to uniformly distribute the elements of array above to this array:
my @tobepopulated = ("foo", "foo", "foo", "foo", "foo", "foo", "foo", +"foo", "foo", "foo"); # this can be more 10 elements
So that in the end I have this new array:
my @new_array = ("foo-x", "foo-x", "foo-x", "foo-y", "foo-y", "foo-y", "foo-z", "foo-z", "foo-z", "foo-z");
Is there a quick way to achieve that?

---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: Uniformly Populating an Array with Elements of Another Array
by roboticus (Chancellor) on Jul 28, 2007 at 10:53 UTC

    neversaint:

    The map & modulus operators are your friends for a job like this.

    #!/usr/bin/perl -w use strict; my @elems = ("x", "y", "z"); my @tobepopulated; push @tobepopulated, "foo" for (1..10); my $cnt=0; my @new_array = map { $_ . "-" . $elems[$cnt++ % @elems] } @tobepopula +ted; print join "\n", @new_array;

    ...roboticus

Re: Uniformly Populating an Array with Elements of Another Array
by GrandFather (Saint) on Jul 28, 2007 at 10:49 UTC

    I'm not sure what you mean by quick, but:

    use strict; use warnings; my @elems = ("x", "y", "z"); my @tobepopulated = ("foo", "foo", "foo", "foo", "foo", "foo", "foo", +"foo", "foo", "foo"); die "Too few elements to populate" unless @tobepopulated ; my $inc = @elems / @tobepopulated; my $elIndex = $inc; for my $to (@tobepopulated) { $to .= "-$elems[$elIndex]"; $elIndex += $inc; } print "@tobepopulated";

    Prints:

    foo-x foo-x foo-x foo-y foo-y foo-y foo-z foo-z foo-z foo-z

    and may be something like what you are after.


    DWIM is Perl's answer to Gödel
Re: Uniformly Populating an Array with Elements of Another Array
by holli (Abbot) on Jul 28, 2007 at 10:58 UTC
    This is quickshot and can surely be optimized
    my @elems = qw(x y z); my @is = qw(foo) x 10; my @new = (); my $i = 0; my $j = 0; my $k = int(@is / @elems)-1; for ( $j=0; $j<@is; $j++ ) { push @new, $is[$j] . $elems[$i]; $i++ if $j % int(@is / @elems) == $k and $i+1<@elems; } print "@new";
    Update: Too late as always ;-)


    holli, /regexed monk/
Re: Uniformly Populating an Array with Elements of Another Array
by Skeeve (Parson) on Jul 28, 2007 at 15:47 UTC
    The standard line-draw algorithm (as far as I can remember) can be used here:
    my @elems = ("x", "y", "z"); # array size may be varied (lesser or more than 3) my @tobepopulated = ("foo", "foo", "foo", "foo", "foo", "foo", "foo", ++"foo", "foo", "foo"); # this can be more 10 elements my $m= 2 * scalar @tobepopulated; my $d= 2 * scalar @elems; die "too few elements to be populated" unless $m >= $d; my $i= 0; my $n= $d/2; foreach (@tobepopulated) { $_.= '-' . $elems[$i]; $n+= $d; if ( $n > $m ) { $n-= $m; ++$i; } } print join "\n",@tobepopulated,'';

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
Re: Uniformly Populating an Array with Elements of Another Array
by jettero (Monsignor) on Jul 28, 2007 at 10:57 UTC
    You may possibly also be looking for (although I kinda doubt it):
    use strict; my @a = (qw(a b c)); my @b = (qw(x y z)); my @c = ( map { my $t = $_; (map { "$t-$_" } @a) } @b );

    -Paul

Re: Uniformly Populating an Array with Elements of Another Array
by jdporter (Paladin) on Jul 29, 2007 at 13:37 UTC

    Here's AWTDI. Where the other solutions seem to be mostly algebraic, this one actually distributes.

    use strict; use warnings; my @elems = qw( x y z ); my @tobepopulated = ('foo') x 10; print "$_\n" for uniformly_distribute( \@elems, @tobepopulated ); sub uniformly_distribute { my $elems_ar = shift; my @c = map { [] } @$elems_ar; while ( @_ ) { for ( reverse ( 0 .. $#c ) ) { push @{ $c[$_] }, join '-', $elems_ar->[$_], pop @_ if @_; } } map @$_, @c }
    A word spoken in Mind will reach its own level, in the objective world, by its own weight