Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

How can I add all the numbers in an array with out doing a foreach loop?

by draco_iii (Acolyte)
on Jun 09, 2000 at 20:14 UTC ( [id://17352]=perlquestion: print w/replies, xml ) Need Help??

draco_iii has asked for the wisdom of the Perl Monks concerning the following question: (arrays)

That is, I want to avoid having to write any kind of explicit loop, such as:
my $sum = 0; for ( @numbers ) { $sum += $_; }
I'd rather do it in a single statement. Of course, I could wrap the above in a sub, but are there any better ways?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How can I add all the numbers in an array with out doing a foreach loop?
by KM (Priest) on Jun 09, 2000 at 20:31 UTC
    The loopish way would be like:

    @e = (1,2,3,4); my $foo; $foo += $_ for @e;

    or you can do something like (still a loop, but you need to loop in some way for this):

    @e = (1,2,3,4); print eval join '+', @e;

    Cheers,
    KM

      You can do it with grep as:

      #!/user/bin/perl use strict; use warnings; my @array = (1,2,3,4,5,6,7,8,9,10); my $sum = 0; grep{$sum += $_} @array; print "\$sum = $sum\n"; exit(0);

      The result is:

      $sum = 55
      ack Albuquerque, NM
      Your first answer is really a foreach loop. Remember that for and foreach are synonyms. Your second answer, however, is very slick! Nice.
        Hence me saying 'The loopish way..'. Actually, they are both loops. I believe internally join() still loops to actually join all the elements. It isn't a loop like a for or foreach.

        Cheers,
        KM

      $ perl -wle'my@x=(0..10);$"="+";$\=~s/$/"@x"/ee;print""' 55 $

      Enjoy, Have FUN! H.Merijn
Re: How can I add all the numbers in an array with out doing a foreach loop?
by brother ab (Scribe) on Sep 15, 2000 at 09:45 UTC

    In functional style, using reduce from List::Util:

    @a = (1..10); use List::Util qw(reduce); $sum = reduce { $a + $b } @a;
Re: How can I add all the numbers in an array with out doing a foreach loop?
by chromatic (Archbishop) on Jun 10, 2000 at 01:17 UTC
    Using eval, which of course has inherent dangers:
    @e = (1,2,3,4); $sum = eval join '+', @e;
Re: How can I add all the numbers in an array with out doing a foreach loop?
by myuserid7 (Scribe) on Aug 15, 2006 at 10:03 UTC
      Just for fun, does the question make any sense?
      use List::Util qw/reduce/; my $sum = reduce { $a + $b } 1..10;
      Boris

      ... and List::Util::sum() doesn't use a foreach loop?

      --
      b10m

      All code is usually tested, but rarely trusted.

        Er, no it is XS code, it does interate over the list it gets as an argument using for(index = 1 ; index < items ; index++) but I don't think that counts as a foreach

        /J\

        A reply falls below the community's threshold of quality. You may see it by logging in.
      I just have to ask how the heck hard is it to write this:

      $sum += $_ for @array

      And notice there's no foreach loop, which the Camel clearly states is a synonym for for anyway (see "perldoc perlsyn", 'Foreach Loops'), so maybe I'm not clear on what you're asking.

      --marmot

Re: How can I add all the numbers in an array with out doing a foreach loop?
by btrott (Parson) on Jun 09, 2000 at 23:42 UTC
    Here's a recursive solution:
    sub sum { @_ ? (shift) + &sum : 0 }
    To be called like:
    print sum(5, 6, 3);

    Originally posted as a Categorized Answer.

Re: How can I add all the numbers in an array with out doing a foreach loop?
by I0 (Priest) on Jan 03, 2001 at 15:49 UTC
    For a positive sum:

    unpack "%123d*" , pack( "d*", @numbers);

    For a signed long:

    unpack "l", pack( "l", unpack( "%32d*", pack( "d*", @numbers)));
Re: How can I add all the numbers in an array with out doing a foreach loop?
by DStaal (Chaplain) on Nov 10, 2009 at 15:08 UTC

    Just to have the one-line loop on here, since your real complaint is to get it all on one line:

    (Note that you'd have to declare $sum someplace before the loop yet.)

    @a = (1..10); $sum += $_ for @a;
Re: How can I add all the numbers in an array with out doing a foreach loop?
by aaron_baugher (Curate) on Oct 20, 2013 at 16:57 UTC

    Surprised no one's added the Lisp-style recursive solution yet:

    sub radd { return( defined $_[0] ? $_[0] + radd(@_[1..$#_]) : 0 ); } my $sum = radd(1..10);
Re: How can I add all the numbers in an array with out doing a foreach loop?
by ack (Deacon) on Nov 09, 2009 at 20:32 UTC

    Can also use map() in a side-effects fashion.

    my @nums = (1,2,3,4,5); my $sum = 0; map { $sum += $_ } @nums; print "\$sum = $sum\n";

    The above code prints:

    $sum = 15

    Originally posted as a Categorized Answer.

Re: How can I add all the numbers in an array with out doing a foreach loop?
by lkench (Initiate) on Jul 08, 2013 at 20:29 UTC
    my $sum = 0; $sum = [map {$sum +=$_} @arrayToSum]->[$#arrayToSum];
      The problem is it does not work under strict and it is probably not doing what you think (it uses a global $sum and lexical $sum at the same time which is confusing).
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      List::Util is CORE:

      use List::Util qw( sum ); my $sum = sum @arrayToSum;

      Enjoy, Have FUN! H.Merijn
Re: How can I add all the numbers in an array with out doing a foreach loop?
by smithfarm (Initiate) on Oct 20, 2013 at 08:19 UTC
    Use the grep function:
    my $sum; grep { $sum += $_ } @arrayToSum;
    Or, equivalently, use the map function:
    my $sum; map { $sum += $_ } @arrayToSum;
    Both grep and map apply the code in the code block to each element of @arrayToSum. The _result_ of the grep/map function is not interesting to us in this case, so we ignore it.

      While these will "work", they confuse the issue of what you are trying to accomplish.

      grep is used to select items from a list.

      map is used to transform one list into another.

      Both take one list and return another list. In my opinion, using grep or map for tasks outside of that scope is being 'too cute', and will cost time later when maintenance time comes around. It takes more work (albeit not much) to comprehend the intent of these code blocks. Make it easier on your future-self and avoid using map and grep for this purpose.

      --MidLifeXis

      It does work, but you'll find that there is a very widespread rule among Perl users which is "Do not use grep or map in a void context". Often the argument is that it is because it uses extra memory for nothing. But Perl is smart enough and turning all uses of grep and map in a void context into a simple for loop could work fine. The problem, as MidLifeXis already said, is not that they don't do it right, is that it's not what they mean.

      A for loop on the contrary was made for this kind of things. And the postfix version is even shorter than a grep or map in this case $sum+=$_ for @array;

Re: How can I add all the numbers in an array with out doing a foreach loop?
by textral (Initiate) on Nov 29, 2017 at 13:55 UTC

    How about as a subroutine?

    sub sumit { my $sum = 0; $sum += pop // return $sum while 1; }

Re: How can I add all the numbers in an array with out doing a foreach loop?
by I0 (Priest) on Jan 03, 2001 at 15:47 UTC
    For a positive sum unpack"%123d*",pack"d*",@_
    For a signed long unpack"l",pack"l",unpack"%32d*",pack"d*",@_

    Originally posted as a Categorized Answer.

Re: How can I add all the numbers in an array with out doing a foreach loop?
by SimonSaysCake (Beadle) on Mar 09, 2017 at 16:51 UTC

    He's a rather ridiculous solution which avoids using the addition operator. It only works for positive integers.

    my @quans = (2, 5, 8, 12, 15, 88); my $total = scalar(map {1 .. $_} @quans); print "$total.\n";
      This is very ineffective way of counting the sum. Try adding 100000000 into the array.

      What your solution does is it creates ranges 1 .. $_ for each number in the list, and then counts how many members the whole sequence has.

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: How can I add all the numbers in an array with out doing a foreach loop?
by rajib (Novice) on Aug 20, 2002 at 17:41 UTC
    Another recursive method:

    @array = (1,2,3); print "SUM: ", sum($#array); sub sum { if ($_[0] == 0) { return $array[0]; } return $array[$_[0]] + sum($_[0]-1); } #note it's not efficient

    This method's shortcoming is that the sub acts only on the global array "@array", and thus can't be easily applied to more than one array. A more elegant and useable recursive method was demonstrated earlier in this thread.

    Originally posted as a Categorized Answer.

Re: How can I add all the numbers in an array with out doing a foreach loop?
by graff (Chancellor) on Jul 20, 2004 at 03:38 UTC
    If you don't like a for loop, maybe a while would be acceptable?
    my @arry = (1..10); my $sum = 0; $sum += pop @arry while @arry; print $sum,$/;

    Originally posted as a Categorized Answer.

Re: How can I add all the numbers in an array with out doing a foreach loop?
by brother ab (Scribe) on Sep 15, 2000 at 09:45 UTC

    Re: How can I add all the numbers in an array with out doing a foreach loop?

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2024-03-28 09:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found