diff --git a/lodash.src.js b/lodash.src.js index a0d9a6f84..9b8a5550a 100644 --- a/lodash.src.js +++ b/lodash.src.js @@ -7387,6 +7387,73 @@ }; } + + /** + * Creates a function that runs each argument through a transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...Function} [transforms] The function to transform the corresponding argument. + * @returns {Function} Returns the new function. + * @example + * + * var square = function(x) { + * return x * x; + * }; + * + * var double = function(x) { + * return x * 2; + * }; + * + * var fn = _.modArgs(function(x, y) { + * return [x , y]; + * }, square, double); + * + * fn(1, 2); // => [1, 4] + * fn(5, 10); // => [25, 20] + * + * // Ensure proper argument types + * + * var defaultNumber = function(defaultValue, num) { + * return _.isUndefined(num) ? defaultValue : num; + * }; + * + * var alwaysArray = function(list) { + * var result = list; + * + * if (_.isUndefined(list)) { + * result = []; + * } else if (!_.isArray(list)) { + * result = [list]; + * } + * + * return result; + * }; + * + * var fn = _.modArgs(function(x, y) { + * console.log(x, y); + * }, alwaysArray, _.partial(defaultNumber, 0)); + * + * fn(); // => [], 0 + * fn('hello'); // => ['hello'], 0 + * fn([true], 15); // => [true], 15 + */ + var modArgs = restParam(function(callback, transforms) { + var length = transforms.length; + + return function() { + var index = -1; + + while (++index < length) { + arguments[index] = transforms[index].call(this, arguments[index]); + } + + return callback.apply(this, arguments); + } + }); + /** * Creates a function that accepts up to `n` arguments ignoring any * additional arguments. @@ -11846,6 +11913,7 @@ // Add functions that return wrapped values when chaining. lodash.after = after; lodash.ary = ary; + lodash.modArgs = modArgs; lodash.assign = assign; lodash.at = at; lodash.before = before; diff --git a/test/test.js b/test/test.js index 1d78c6c28..929ddd87d 100644 --- a/test/test.js +++ b/test/test.js @@ -959,6 +959,52 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.modArgs'); + + (function() { + function double(x) { + return x * 2; + } + + function square(x) { + return x * x; + } + + function fn() { + return Array.prototype.slice.call(arguments, 0); + } + + test('should transform each argument', 1, function() { + var wrapped = _.modArgs(fn, double, square); + var actual = wrapped(5, 10); + + deepEqual(actual, [10, 100]); + }); + + test('should not transform any argument greater than the number of transforms', 1, function() { + var wrapped = _.modArgs(fn, double, square); + var actual = wrapped(5, 10, 18); + + deepEqual(actual, [10, 100, 18]); + }); + + test('should not transform any arguments if no transforms are provided', 1, function() { + var wrapped = _.modArgs(fn); + var actual = wrapped(5, 10, 18); + + deepEqual(actual, [5, 10, 18]); + }); + + test('should not pass undefined if transforms > arguments', 1, function() { + var wrapped = _.modArgs(fn, double, _.identity); + var actual = wrapped(5); + + deepEqual(actual, [10]); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.ary'); (function() { @@ -17877,7 +17923,7 @@ var acceptFalsey = _.difference(allMethods, rejectFalsey); - test('should accept falsey arguments', 225, function() { + test('should accept falsey arguments', 226, function() { var emptyArrays = _.map(falsey, _.constant([])), isExposed = '_' in root, oldDash = root._;