From 06316f1d474b07489adaa790886cf1b73cb6737d Mon Sep 17 00:00:00 2001 From: Tucker Whitehouse Date: Thu, 24 Mar 2016 15:37:07 -0400 Subject: [PATCH] Add _.meanBy. --- fp/_mapping.js | 2 +- lodash.js | 32 ++++++++++++++++++++++++++++-- test/test.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/fp/_mapping.js b/fp/_mapping.js index 3ea6c1331..1dddc8022 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -67,7 +67,7 @@ exports.aryMethod = { 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', - 'matchesProperty', 'maxBy', 'merge', 'minBy', 'multiply', 'omit', 'omitBy', + 'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'restFrom', 'result', diff --git a/lodash.js b/lodash.js index 663c577bd..ed655d8bb 100644 --- a/lodash.js +++ b/lodash.js @@ -1513,7 +1513,7 @@ * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, - * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `maxBy`, `mean`, `meanBy`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, @@ -14820,7 +14820,34 @@ * // => 5 */ function mean(array) { - return sum(array) / (array ? array.length : 0); + return meanBy(array, identity); + } + + /** + * This method is like `_.mean` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the value to be averaged. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the mean. + * @example + * + * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; + * + * _.meanBy(objects, function(o) { return o.n; }); + * // => 5 + * + * // The `_.property` iteratee shorthand. + * _.meanBy(objects, 'n'); + * // => 5 + */ + function meanBy(array, iteratee) { + return sumBy(array, iteratee) / (array ? array.length : 0); } /** @@ -15240,6 +15267,7 @@ lodash.max = max; lodash.maxBy = maxBy; lodash.mean = mean; + lodash.meanBy = meanBy; lodash.min = min; lodash.minBy = minBy; lodash.multiply = multiply; diff --git a/test/test.js b/test/test.js index 3185c08a6..a773da7e0 100644 --- a/test/test.js +++ b/test/test.js @@ -12010,6 +12010,19 @@ } }); + QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) { + assert.expect(1); + + if (!isModularize) { + _.iteratee = getPropA; + assert.strictEqual(_.meanBy(objects), 2 / 3); + _.iteratee = iteratee; + } + else { + skipAssert(assert); + } + }); + QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) { assert.expect(1); @@ -13958,6 +13971,44 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.meanBy'); + + (function() { + var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }]; + + QUnit.test('should work with an `iteratee` argument', function(assert) { + assert.expect(1); + + var actual = _.meanBy(objects, function(object) { + return object.a; + }); + + assert.deepEqual(actual, 2); + }); + + QUnit.test('should provide the correct `iteratee` arguments', function(assert) { + assert.expect(1); + + var args; + + _.meanBy(objects, function() { + args || (args = slice.call(arguments)); + }); + + assert.deepEqual(args, [{ 'a': 2 }]); + }); + + QUnit.test('should work with "_.property" shorthands', function(assert) { + assert.expect(2); + + var arrays = [[2], [3], [1]]; + assert.strictEqual(_.meanBy(arrays, 0), 2); + assert.strictEqual(_.meanBy(objects, 'a'), 2); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.memoize'); (function() { @@ -25146,7 +25197,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(307); + assert.expect(308); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);