From e91a662491146da1c25e25e4da234c8bcafd00b3 Mon Sep 17 00:00:00 2001 From: Nicolas Chambrier Date: Sat, 7 Feb 2015 20:28:34 +0100 Subject: [PATCH] Add _.spread. --- lodash.src.js | 40 ++++++++++++++++++++++++++++++++++++++++ test/test.js | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/lodash.src.js b/lodash.src.js index 404872129..dbe7c46d1 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -7579,6 +7579,45 @@ return createWrapper(func, REARG_FLAG, null, null, null, indexes); } + /** + * Creates a function accepting an array as argument, that invokes `func` + * with arguments taken from this array, like `Function#apply`. + * This works obviously well with `Promise.all`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} The function to alter. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {*} Returns the new function. + * @example + * + * var spread = _.spread(function (who, what) { + * return who + ' says ' + what; + * }); + * + * spread(['John', 'hello']) // => 'John says hello' + * + * // With Promise + * var numbers = Promise.all([ + * Promise.resolve(42), + * Promise.resolve(33) + * ]) + * + * numbers.then(_.spread(function (a, b) { return a + b })) // Promise of 75 + * // instead of... + * numbers.then(function (nums) { return nums[0] + nums[1] }) + */ + function spread (func, thisArg) { + if (typeof func !== 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + + return function(array) { + return func.apply(thisArg, array); + }; + } + /** * Creates a function that only invokes `func` at most once per every `wait` * milliseconds. The created function comes with a `cancel` method to cancel @@ -10752,6 +10791,7 @@ lodash.slice = slice; lodash.sortBy = sortBy; lodash.sortByAll = sortByAll; + lodash.spread = spread; lodash.take = take; lodash.takeRight = takeRight; lodash.takeRightWhile = takeRightWhile; diff --git a/test/test.js b/test/test.js index afeab682f..03b30c98f 100644 --- a/test/test.js +++ b/test/test.js @@ -12240,6 +12240,53 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.spread'); + + (function() { + function Pair(x, y) { + this.x = x; + this.y = y; + + return 42; + } + + function divide(n, d) { + return n / d; + } + + test('should pass arguments to `func`', 1, function() { + var spread = _.spread(divide); + strictEqual(spread([4, 2]), 2); + }); + + test('should fail when receiving non-array argument', 1, function() { + var spread = _.spread(divide); + var err; + try { + spread(4, 2); + } catch (e) { + err = e; + } + strictEqual(_.isError(err), true); + }); + + test('should dynamically `func` to `thisArg`', 2, function() { + var self = {z: 3}; + var spread = _.spread(Pair, self); + var result = spread([1, 2]); + strictEqual(result, 42); + deepEqual(self, {x: 1, y: 2, z: 3}); + }); + + test('should use `undefined` for extra values', 1, function() { + var self = {}; + _.spread(Pair, self)([1]); + deepEqual(self, {x: 1, y: undefined}); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.support'); (function() { @@ -14960,6 +15007,7 @@ 'partial', 'partialRight', 'rearg', + 'spread', 'throttle' ]; @@ -15078,7 +15126,7 @@ }); }); - test('should throw an error for falsey arguments', 22, function() { + test('should throw an error for falsey arguments', 23, function() { _.each(rejectFalsey, function(methodName) { var expected = _.map(falsey, _.constant(true)), func = _[methodName];