Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Filling an array

by Anonymous Monk
on Sep 06, 2001 at 19:55 UTC ( [id://110603]=perlquestion: print w/replies, xml ) Need Help??

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

Monks: I have an array that I need to initialize all with the same value. This array was originally 10 long, so it was easy:
my @arr = (1,1,1,1,1,1,1,1,1,1);
But now it has to be size 100! Is there any way I can fill it with all ones without typeing 100 ones?

Replies are listed 'Best First'.
Re: Filling an array
by robsv (Curate) on Sep 06, 2001 at 19:57 UTC
    Use the x (repetition) operator:
    my @arr = (1)x100;
    Don't forget the parens around the 1 - if they're not there, you'll end up with an array containing one element: 100 1s concatenated together.

    - robsv
      Cool! Didn't know of the x operator....

      ----
      Zak
Re: Filling an array
by dragonchild (Archbishop) on Sep 06, 2001 at 20:17 UTC
    The repetition operator is good if you want 100 of the same value. However, if you want all the multiples of 3, you need to do a for-loop or a map. Something like:
    my $multiple = 3; my @arr = map { $_ * $multiple } (0 .. 100); # Or, you could do a for-loop my $multiple = 3; my @arr; $arr[$_] = $_ * $multiple for (0 .. 100);
    Note that all these solutions give 101 values, the 0th value being the first and the 100th value being the hundred-and-first. If you want only the first 100, do (0 .. 99) instead.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Vote paco for President!

Re: Filling an array
by broquaint (Abbot) on Sep 06, 2001 at 23:20 UTC
    If you just want an array filled with 100 values you could make effective use of the range operator -
    @arr = 1..100;
    Now it'll be filled with the numbers from 1 to 100, handy.

    broquaint

Re: Filling an array
by jryan (Vicar) on Sep 06, 2001 at 20:08 UTC

    You can either use a for loop:

    my @arr; for (my $i=0; $i<100; $i++) { $arr[$i]=1}

    or the x operator:

    my @arr = (1)x100;
Re: Filling an array
by spartan (Pilgrim) on Sep 07, 2001 at 02:00 UTC
    ++dragonchild
    I was inspired by your map example to do something like this instead:
    $value=" 1 "; @array=map {$_=$value} (1..100); $i=0; foreach (@array) { print "$i $_\n"; $i++; }
    The $i variable (used as an incrementer) and the foreach merely proves the map statement.
    -spartan

    Very funny Scotty... Now PLEASE beam down my PANTS!
      You can eliminate the $i var by doing the following:

      for (0 .. $#array) { print "$_ $array[$_]\n" }

      Also, I would think you'd be better off using one of the other suggestions like for() or the x operator rather than map() for efficiency reasons.

      Zenon Zabinski | zdog | zdog7@hotmail.com

        ++zdog
        for (0 .. $#array) { print "$_ $array[$_]\n" }
        I like that... very clean, to the point, and quite readable. The only reason I chose map was to flex an all too atrophied brain muscle. :)
        TMTOWTDI

        Very funny Scotty... Now PLEASE beam down my PANTS!
Re: Filling an array
by Anonymous Monk on Sep 07, 2001 at 05:49 UTC
    my @arr=split('',"(1"x100));
Re: Filling an array
by Anonymous Monk on Sep 07, 2001 at 14:05 UTC
Re: Filling an array
by fridden (Initiate) on Sep 07, 2001 at 12:06 UTC
    @Array = split / /, "1 " x 100;
Re: Filling an array
by Anonymous Monk on Sep 07, 2001 at 07:57 UTC
    It is not polite to push others, but arrays are an exception:

    my @arr = ();

    for ($i=1; $i=100; $i++)
    { push(@arr,1);
    }
      Turn on warnings with that code.... I think you'll find a critical (but easy to make) bug in the above code.

      -Blake

      Doh, you are correct. I changed usually use for loop code like this:

      for ($i=0; $<100; $i++) { push(@arr,1); }

      but that was before I knew about the CODE tags, so I figured it would be easier to just change it to an equal sign. I forgot you needed two of them :)
        I like this style of for loop, since there are fewer
        chances for a typo:
        push(@array,1) for(0..99);

        And you can incorporate the multiplier with your push:
        push(@array, $_ * 3) for(0..99);

        -blyman

The defensive programming way to fill an array
by petdance (Parson) on Sep 09, 2001 at 08:53 UTC
    Your situation is a perfect example of why you should never type anything more than once for a specific amount: If you're doing it a few times now, you'll be doing it more in the future.

    In this case, you just happened to be able to fill up the array with ten ones. Later on, you had to change that to 100. As a programmer, you should count on that happening and plan accordingly.

    What's more, the actual number of items in the list needs to be made clear. If I'm trying to read your code, and I'm wondering how many ones there are, I have to count. That's not fun. Never mind you having to type 100 ones: What about the next person to read your code (who could be you) having to count those 100 ones.

    Why are there 100 ones? I don't know, and your code doesn't tell me. Is it the number of wangos that you're processing? Then comment it:

    my @arr = (1) x 10; # We can process 10 wangos.
    Better yet, define a variable that tells how many wangos you can process:
    my $max_wangos = 10; my @arr = (1) x $max_wangos;
    Best of all, define a constant that is easily changeable AND describes what you're doing:
    use strict MAX_WANGOS => 10; my @arr = (1) x MAX_WANGOS;
    An excellent book that these concepts, and many many more, is Steve McConnell's excellent Code Complete. No serious programmer should be without it.

    xoxo,
    Andy
    --
    <megaphone> Throw down the gun and tiara and come out of the float! </megaphone>

Re: Filling an array
by shagbark (Acolyte) on Mar 21, 2018 at 14:20 UTC
    File time-array-init.pl tests how long each method of initializing and filling an array takes:
    use Time::HiRes qw(gettimeofday); use strict; use warnings; sub timeSub { my ($sub, @parms) = @_; my ($sec0, $micro0)=gettimeofday; my $name = $sub->(1000000, @parms); my ($sec1, $micro1)=gettimeofday; my $diff = 1000000*($sec1-$sec0) + $micro1-$micro0; print "$name:\t$diff microseconds\n"; } sub pushInit { my $loops = shift; my @x; for (my $i=0; $i<$loops; $i++) { push(@x, 1) } return "push"; } sub elInit { my $loops = shift; my @x; for (my $i=0; $i<$loops; $i++) { $x[$i] = 1 } return "\$a[\$i]"; } sub xInit { my $loops = shift; my @x = (1) x $loops; return "(1) x"; } # This method builds the array (1, 2, 3, ...), not (1, 1, 1, ...) sub dotInit { my $loops = shift; my @x = 1..$loops; return ".."; } foreach my $subR (\&pushInit, \&elInit, \&xInit, \&dotInit) { &timeSub($subR); }
    Running it:
    $ perl time-array-init.pl push: 171028 microseconds $a[$i]: 163881 microseconds (1) x: 51077 microseconds ..: 70115 microseconds
    I would guess that the first 2 methods also consume a lot more memory, as Perl 5 isn't good at reclaiming memory from deleted objects.
      Perl 5 isn't good at reclaiming memory from deleted objects.

      What grounds do you have for this assertion, please?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://110603]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-19 23:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found