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

Hi. I am Fighter2. I am a seeker of Perl Wisdom.

Say, for example, I have two arrays @a and @b, and @b is 11 elements in length.

There is a certain scalar $x whose value needs to be the first element @a. If scalar $x is 4, then I need to copy @b 4 times to @a after $x is copied (hence we will be pushing @b). So array @a will have 1 + 11 *4 elements = 45. If $x is 2, then I need to copy @b 2 times to @a. $x is a variable, and can range from 0 to 6.

@b is constantly being written to @a as many $x times by a loop.

Here. This will give you a small idea

do{ my @a; push @a, $x; for(my $i=0;$i<$x;$i++){ #for each sector for(my $j=0;$j<$numFngs;$j++){ push @b, $obj->{sectors}->{$sector}->{$j}->{c2i}; } push @a, @b; } $x=update($x); }while (certain event to end);

Now, what I dont know how to make is this,.. One single record of @a should contain 49 elements at any given time. because I am reading 49 elements at a time. First element is the value from $x, and the rest is $x times of @b. But if $x is less than 6, then the rest of that 49 elements should be padded with zeros. The reason for this is, I want to be able to read the array @a from every instance of $x. If I know @a always has $x coming at every 49th element, this is easy. How do I make a loop like this to make @a?

Replies are listed 'Best First'.
Re: I need some wisdom. How do I pack an array to a set length.
by ikegami (Patriarch) on Nov 23, 2011 at 20:27 UTC
    my @a = $x; push @a, @b for 1..$x;
    or
    my @a = ( $x, map { @b } 1..$x );
    or
    my @a = ( $x, (@b) x $x );

    The inner parens are required since "()x" is different than just "x".

Re: I need some wisdom. How do I pack an array to a set length.
by mr.nick (Chaplain) on Nov 23, 2011 at 20:28 UTC
    The "x" operator works with arrays lists as well:
    @b=qw(h o r s e ); $x=4; push @a,$x,((@b) x $x); print join(",",@a);
    Edit: /nods to Tux; yeah, sometimes I forget my terminology.

    mr.nick ...

      Though you're example is perfect, your wording is not. x works also on lists, not on arrays:

      $ perl -E'@x=("a".."c");@y=@x x 3;say@y' 333 $ perl -E'@x=("a".."c");@y=(@x)x 3;say@y' abcabcabc $

      That is why the extra parens are needed, otherwise the array would be evaluated in scalar context by x and hence returns its length.


      Enjoy, Have FUN! H.Merijn
Re: I need some wisdom. How do I pack an array to a set length.
by jwkrahn (Abbot) on Nov 23, 2011 at 21:59 UTC
    $ perl -le' my @b = 21 .. 31; print scalar @b; my $x = 3; my $length = 49; my @a = ( $x, ( @b ) x $x, ( 0 ) x $length )[ 0 .. $length - 1 ]; print scalar @a, ": @a"; ' 11 49: 3 21 22 23 24 25 26 27 28 29 30 31 21 22 23 24 25 26 27 28 29 30 3 +1 21 22 23 24 25 26 27 28 29 30 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Re: I need some wisdom. How do I pack an array to a set length.
by Marshall (Canon) on Nov 24, 2011 at 06:55 UTC
    I don't understand this premise: The reason for this is, I want to be able to read the array @a from every instance of $x. If I know @a always has $x coming at every 49th element, this is easy.

    Could you explain more about your application?
    I have no problem with some of the solutions in this thread to create this array with redundant information. But I am confused as to why this would be necessary or "easy"?

Re: I need some wisdom. How do I pack an array to a set length.
by TJPride (Pilgrim) on Nov 24, 2011 at 09:01 UTC
    $x = 4; @b = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); $a[0] = $x; push @a, @b for 1..$x; push @a, 0 while $#a < 48; print "@a";

    This makes very little logical sense, of course, because you say you want a maximum of 49 elements, yet if @b has 11 elements, then any value of $x larger than 4 will go over the 49. It might be more helpful if you gave us a sample of your actual input data and an example of what you want it to come out like.