From 6eb0cb156505adfb5356fd67255c131055c637c8 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 19 Mar 2016 21:00:29 -0700 Subject: [PATCH] Add `_.divide` and `_.multiply`. --- fp/_mapping.js | 36 ++++++++++--------- lodash.js | 95 +++++++++++++++++++++++++++++++++++-------------- test/test-fp.js | 17 ++++++++- test/test.js | 14 ++++---- 4 files changed, 111 insertions(+), 51 deletions(-) diff --git a/fp/_mapping.js b/fp/_mapping.js index cec7a68ea..a7c4df579 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -52,23 +52,23 @@ exports.aryMethod = { 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', - 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', - 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', - 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth', 'forEach', 'forEachRight', - 'forIn', 'forInRight', 'forOwn', 'forOwnRight', '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', - 'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', - 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', - 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', 'repeat', - 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', - 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', - 'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', - 'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', - 'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', - 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', - 'zipObjectDeep' + 'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', + 'eq', 'every', 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', + 'findLastIndex', 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth', + 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', + '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', + 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', 'partialRight', + 'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', 'random', 'range', + 'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'restFrom', 'result', + 'sampleSize', 'some', 'sortBy', 'sortedIndex', 'sortedIndexOf', 'sortedLastIndex', + 'sortedLastIndexOf', 'sortedUniqBy', 'split', 'spreadFrom', 'startsWith', + 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'tap', + 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', 'trimCharsStart', + 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', 'unzipWith', 'without', + 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' ], '3': [ 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', @@ -248,12 +248,14 @@ exports.skipRearg = { 'assignIn': true, 'concat': true, 'difference': true, + 'divide': true, 'gt': true, 'gte': true, 'lt': true, 'lte': true, 'matchesProperty': true, 'merge': true, + 'multiply': true, 'partial': true, 'partialRight': true, 'random': true, diff --git a/lodash.js b/lodash.js index 22f88ec2f..0586c68e8 100644 --- a/lodash.js +++ b/lodash.js @@ -1074,6 +1074,29 @@ return result; } + /** + * Creates a function that performs a mathematical operation on two values. + * + * @private + * @param {Function} operator The function to perform the operation. + * @returns {Function} Returns the new mathematical operation function. + */ + function createMathOperation(operator) { + return function(value, other) { + var result; + if (value === undefined && other === undefined) { + return 0; + } + if (value !== undefined) { + result = value; + } + if (other !== undefined) { + result = result === undefined ? other : operator(result, other); + } + return result; + }; + } + /** * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. * @@ -14615,19 +14638,9 @@ * _.add(6, 4); * // => 10 */ - function add(augend, addend) { - var result; - if (augend === undefined && addend === undefined) { - return 0; - } - if (augend !== undefined) { - result = augend; - } - if (addend !== undefined) { - result = result === undefined ? addend : (result + addend); - } - return result; - } + var add = createMathOperation(function(augend, addend) { + return augend + addend; + }); /** * Computes `number` rounded up to `precision`. @@ -14652,6 +14665,25 @@ */ var ceil = createRound('ceil'); + /** + * Divide two numbers. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Math + * @param {number} dividend The first number in a division. + * @param {number} divisor The second number in a division. + * @returns {number} Returns the quotient. + * @example + * + * _.divide(6, 4); + * // => 1.5 + */ + var divide = createMathOperation(function(dividend, divisor) { + return dividend / divisor; + }); + /** * Computes `number` rounded down to `precision`. * @@ -14799,6 +14831,25 @@ : undefined; } + /** + * Multiply two numbers. + * + * @static + * @memberOf _ + * @since 4.7.0 + * @category Math + * @param {number} multiplier The first number in a multiplication. + * @param {number} multiplicand The second number in a multiplication. + * @returns {number} Returns the product. + * @example + * + * _.multiply(6, 4); + * // => 24 + */ + var multiply = createMathOperation(function(multiplier, multiplicand) { + return multiplier * multiplicand; + }); + /** * Computes `number` rounded to `precision`. * @@ -14837,19 +14888,9 @@ * _.subtract(6, 4); * // => 2 */ - function subtract(minuend, subtrahend) { - var result; - if (minuend === undefined && subtrahend === undefined) { - return 0; - } - if (minuend !== undefined) { - result = minuend; - } - if (subtrahend !== undefined) { - result = result === undefined ? subtrahend : (result - subtrahend); - } - return result; - } + var subtract = createMathOperation(function(minuend, subtrahend) { + return minuend - subtrahend; + }); /** * Computes the sum of the values in `array`. @@ -15076,6 +15117,7 @@ lodash.cloneDeepWith = cloneDeepWith; lodash.cloneWith = cloneWith; lodash.deburr = deburr; + lodash.divide = divide; lodash.endsWith = endsWith; lodash.eq = eq; lodash.escape = escape; @@ -15155,6 +15197,7 @@ lodash.mean = mean; lodash.min = min; lodash.minBy = minBy; + lodash.multiply = multiply; lodash.noConflict = noConflict; lodash.noop = noop; lodash.now = now; diff --git a/test/test-fp.js b/test/test-fp.js index 6061b878e..3ee9d3d44 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -929,7 +929,7 @@ var func = fp[methodName], isAdd = methodName == 'add'; - QUnit.test('`fp.' + methodName + '` should have `rearg` applied', function(assert) { + QUnit.test('`fp.' + methodName + '` should not have `rearg` applied', function(assert) { assert.expect(1); assert.strictEqual(func('1')('2'), isAdd ? '12' : -1); @@ -1021,6 +1021,21 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('fp.divide and fp.multiply'); + + _.each(['divide', 'multiply'], function(methodName) { + var func = fp[methodName], + isDivide = methodName == 'divide'; + + QUnit.test('`fp.' + methodName + '` should not have `rearg` applied', function(assert) { + assert.expect(1); + + assert.strictEqual(func('2')('4'), isDivide ? 0.5 : 8); + }); + }); + + /*--------------------------------------------------------------------------*/ + QUnit.module('fp.extend'); (function() { diff --git a/test/test.js b/test/test.js index ec4425850..04b3f7f22 100644 --- a/test/test.js +++ b/test/test.js @@ -24677,11 +24677,13 @@ (function() { var funcs = [ + 'add', 'camelCase', 'capitalize', 'ceil', 'clone', 'deburr', + 'divide', 'endsWith', 'escape', 'escapeRegExp', @@ -24731,6 +24733,7 @@ 'maxBy', 'min', 'minBy', + 'multiply', 'pad', 'padEnd', 'padStart', @@ -24749,6 +24752,7 @@ 'some', 'startCase', 'startsWith', + 'subtract', 'sum', 'toInteger', 'toLower', @@ -24770,9 +24774,7 @@ assert.expect(1); if (!isNpm) { - var array = [1, 2, 3], - actual = _(array)[methodName](); - + var actual = _()[methodName](); assert.notOk(actual instanceof _); } else { @@ -24784,9 +24786,7 @@ assert.expect(1); if (!isNpm) { - var array = [1, 2, 3], - actual = _(array).chain()[methodName](); - + var actual = _().chain()[methodName](); assert.ok(actual instanceof _); } else { @@ -25012,7 +25012,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(305); + assert.expect(307); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);