Here's code for sum_by and sum0_by.
diff --git a/Changes b/Changes
index 1b80d16..5b68b44 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
Revision history for List-UtilsBy
+NEXT
+ [CHANGES]
+ * Added 'sum_by' and 'sum0_by'
+
0.10 2015/07/16 19:22:00
[CHANGES]
* Added 'extract_first_by'
diff --git a/MANIFEST b/MANIFEST
index 1e78fde..c3ebef4 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -20,5 +20,6 @@ t/09unzip_by.t
t/10extract_by.t
t/11weighted_shuffle_by.t
t/12bundle_by.t
+t/13sum_by.t
t/99pod.t
t/Unrandom.pm
diff --git a/lib/List/UtilsBy.pm b/lib/List/UtilsBy.pm
index 0ff59f9..827758a 100644
--- a/lib/List/UtilsBy.pm
+++ b/lib/List/UtilsBy.pm
@@ -1,7 +1,7 @@
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
-# (C) Paul Evans, 2009-2015 -- leonerd@leonerd.org.uk
+# (C) Paul Evans, 2009-2017 -- leonerd@leonerd.org.uk
package List::UtilsBy;
@@ -21,6 +21,8 @@ our @EXPORT_OK = qw(
max_by nmax_by
min_by nmin_by
+ sum_by sum0_by
+
uniq_by
partition_by
@@ -255,6 +257,64 @@ sub min_by(&@)
*nmin_by = \&min_by;
+=head2 sum_by
+
+=head2 sum0_by
+
+ $sum = sum_by { VALUEFUNC } @vals;
+
+ $sum = sum0_by { VALUEFUNC } @vals;
+
+Returns the sum of the results of VALUEFUNC applied to each of the values
+in C<@vals>.
+
+For example:
+
+ $total_salary = sum_by { $_->salary } @employees;
+
+This is the same as using C<sum> from L<List::Util> like
+
+ $total_salary = sum map { $_->salary } @employees;
+
+but without the intermediate results of the C<map>.
+
+If called on an empty list, C<sum_by> returns undef, and C<sum0_by>
+returns 0.
+
+=cut
+
+sub sum_by(&@)
+{
+ my $code = shift;
+
+ return undef unless @_;
+
+ local $_;
+
+ my $sum = 0;
+
+ foreach ( @_ ) {
+ $sum += $code->();
+ }
+
+ return $sum;
+}
+
+sub sum0_by(&@)
+{
+ my $code = shift;
+
+ local $_;
+
+ my $sum = 0;
+
+ foreach ( @_ ) {
+ $sum += $code->();
+ }
+
+ return $sum;
+}
+
=head2 uniq_by
@vals = uniq_by { KEYFUNC } @vals
diff --git a/t/13sum_by.t b/t/13sum_by.t
new file mode 100644
index 0000000..b39feff
--- /dev/null
+++ b/t/13sum_by.t
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use List::UtilsBy qw( sum_by sum0_by );
+
+my @employees = (
+ Employee->new( 50_000 ),
+ Employee->new( 90_000 ),
+ Employee->new( 75_000 ),
+);
+
+SUM: {
+ my $sum;
+ $sum = sum_by { $_ * 9 } 1..10;
+ is( $sum, 495, 'Mulitplication on sum_by' );
+
+ $sum = sum_by { $_ * $_ } ();
+ is( $sum, undef, 'Empty list = undef' );
+
+ $sum = sum_by { $_->salary } @employees;
+ is( $sum, 215_000, 'Salary sum' );
+}
+
+
+SUM0: {
+ my $sum0;
+ $sum0 = sum0_by { $_ * 9 } 1..10;
+ is( $sum0, 495, 'Mulitplication on sum0_by' );
+
+ $sum0 = sum0_by { $_ * $_ } ();
+ is( $sum0, 0, 'Empty list = undef' );
+
+ $sum0 = sum0_by { $_->salary } @employees;
+ is( $sum0, 215_000, 'Salary sum0' );
+}
+
+done_testing;
+
+exit 0;
+
+package Employee;
+
+sub new {
+ my $class = shift;
+ my $salary = shift;
+
+ return bless { salary => $salary }, $class;
+}
+
+sub salary {
+ my $self = shift;
+
+ return $self->{salary};
+}