From 03478afea411d27e13b0ea2819a2901e4718fa76 Mon Sep 17 00:00:00 2001 From: qsona Date: Mon, 16 Mar 2015 00:47:54 +0900 Subject: [PATCH] Add support for `_.sum` to take iteratee. --- lodash.src.js | 31 +++++++++++++++++++++++++++++-- test/test.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/lodash.src.js b/lodash.src.js index a42dc037b..7996f8892 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -11304,6 +11304,8 @@ * @memberOf _ * @category Math * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. * @returns {number} Returns the sum. * @example * @@ -11312,16 +11314,41 @@ * * _.sum({ 'a': 4, 'b': 6, 'c': 2 }); * // => 12 + * + * _.sum([]); + * // => 0 + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.sum(users, function(chr) { + * return chr.age; + * }); + * // => 76 + * + * // using the `_.property` callback shorthand + * _.sum(users, 'age'); + * // => 76 */ - function sum(collection) { + function sum(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } if (!isArray(collection)) { collection = toIterable(collection); } + var func = getCallback(); + if (!(func === baseCallback && iteratee == null)) { + iteratee = func(iteratee, thisArg, 3); + } + var length = collection.length, result = 0; while (length--) { - result += +collection[length] || 0; + result += +(iteratee == null ? collection[length] : iteratee(collection[length])) || 0; } return result; } diff --git a/test/test.js b/test/test.js index 2e9ec5273..11973bf3d 100644 --- a/test/test.js +++ b/test/test.js @@ -2984,6 +2984,17 @@ } }); + test('`_.sum` should use `_.callback` internally', 1, function() { + if (!isModularize) { + _.callback = getPropB; + strictEqual(_.sum(objects), 1); + _.callback = callback; + } + else { + skipTest(); + } + }); + test('`_.takeRightWhile` should use `_.callback` internally', 1, function() { if (!isModularize) { _.callback = getPropB; @@ -13464,6 +13475,8 @@ QUnit.module('lodash.sum'); (function() { + var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; + test('should return the sum of an array of numbers', 1, function() { strictEqual(_.sum([6, 4, 2]), 12); }); @@ -13491,6 +13504,40 @@ strictEqual(_.sum(value), 6); }); }); + + test('should work with an `iteratee` argument', 1, function() { + var actual = _.sum(objects, function(object) { + return object.a; + }); + + deepEqual(actual, 6); + }); + + test('should support the `thisArg` argument', 1, function() { + var actual = _.sum([1, 2.5, 1.5], function(num) { + return this.floor(num); + }, Math); + + strictEqual(actual, 4); + }); + + test('should work with a "_.property" style `iteratee`', 2, function() { + var actual = _.sum(objects, 'a'); + + strictEqual(actual, 6); + + var arrays = [[2], [3], [1]]; + actual = _.sum(arrays, 0); + + strictEqual(actual, 6); + }); + + test('should perform basic sum when used as an iteratee for methods like `_.map`', 1, function() { + var array = [{ 'a': 1, 'b': 2, 'c': 3 }, [1, 2, 1]], + actual = _.map(array, _.sum); + + deepEqual(actual, [6, 4]); + }); }()); /*--------------------------------------------------------------------------*/