From cf26447f7c72fe9c660605983311d983f7cdf987 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 26 Jul 2013 09:12:04 -0700 Subject: [PATCH] Add `_.indexBy` method and add a `noop` fallback for `setBindData`. Former-commit-id: f8035b9a221ba7b625c21cb566c62931877da6ef --- build.js | 62 ++++++++++---- build/pre-compile.js | 1 + dist/lodash.compat.js | 134 ++++++++++++++++++++++--------- dist/lodash.compat.min.js | 83 ++++++++++--------- dist/lodash.js | 147 +++++++++++++++++++++++----------- dist/lodash.min.js | 84 +++++++++---------- dist/lodash.underscore.js | 88 +++++++++++--------- dist/lodash.underscore.min.js | 60 +++++++------- lodash.js | 129 ++++++++++++++++++++--------- test/test-build.js | 2 + 10 files changed, 498 insertions(+), 292 deletions(-) diff --git a/build.js b/build.js index d3c571375..641bad19c 100644 --- a/build.js +++ b/build.js @@ -103,7 +103,7 @@ 'compact': [], 'compose': [], 'contains': ['baseEach', 'getIndexOf', 'isString'], - 'countBy': ['createCallback', 'forEach'], + 'countBy': ['createAggregator'], 'createCallback': ['baseIsEqual', 'bind', 'identity', 'isObject', 'keys', 'setBindData'], 'debounce': ['isObject'], 'defaults': ['createCallback', 'createIterator'], @@ -122,9 +122,10 @@ 'forIn': ['createIterator'], 'forOwn': ['createIterator'], 'functions': ['forIn', 'isFunction'], - 'groupBy': ['createCallback', 'forEach'], + 'groupBy': ['createAggregator'], 'has': [], 'identity': [], + 'indexBy': ['createAggregator'], 'indexOf': ['baseIndexOf', 'sortedIndex'], 'initial': ['createCallback', 'slice'], 'intersection': ['cacheIndexOf', 'createCache', 'getArray', 'getIndexOf', 'releaseArray', 'releaseObject'], @@ -208,6 +209,7 @@ 'cachePush': [], 'charAtCallback': [], 'compareAscending': [], + 'createAggregator': ['createCallback', 'forEach'], 'createBound': ['createObject', 'isFunction', 'isObject', 'setBindData'], 'createCache': ['cachePush', 'getObject', 'releaseObject'], 'createIterator': ['getObject', 'isArguments', 'isArray', 'isString', 'iteratorTemplate', 'lodash', 'releaseObject'], @@ -224,7 +226,7 @@ 'noop': [], 'releaseArray': [], 'releaseObject': [], - 'setBindData': [], + 'setBindData': ['noop'], 'shimIsPlainObject': ['forIn', 'isArguments', 'isFunction', 'isNode'], 'shimKeys': ['createIterator'], 'slice': [], @@ -324,6 +326,7 @@ 'findWhere', 'forEach', 'groupBy', + 'indexBy', 'invoke', 'map', 'max', @@ -514,6 +517,7 @@ 'findKey', 'forIn', 'forOwn', + 'indexBy', 'isPlainObject', 'merge', 'parseInt', @@ -1185,7 +1189,7 @@ * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `createObject` fork. + * @returns {String} Returns the fork. */ function getCreateObjectFork(source) { var result = source.match(/(?:\s*\/\/.*)*\n( *)if *\((?:!nativeCreate)[\s\S]+?\n *};\n\1}/); @@ -1197,7 +1201,7 @@ * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `_.defer` fork. + * @returns {String} Returns the fork. */ function getDeferFork(source) { var result = source.match(/(?:\s*\/\/.*)*\n( *)if *\(isV8 *&& *freeModule[\s\S]+?\n\1}/); @@ -1318,7 +1322,7 @@ * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `isArguments` fork. + * @returns {String} Returns the fork. */ function getIsArgumentsFork(source) { var result = source.match(/(?:\s*\/\/.*)*\n( *)if *\((?:!support\.argsClass|!isArguments)[\s\S]+?\n *};\n\1}/); @@ -1330,7 +1334,7 @@ * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `isArray` fork. + * @returns {String} Returns the fork. */ function getIsArrayFork(source) { return matchFunction(source, 'isArray') @@ -1343,7 +1347,7 @@ * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `isFunction` fork. + * @returns {String} Returns the fork. */ function getIsFunctionFork(source) { var result = source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?\n *};\n\1}/); @@ -1392,12 +1396,24 @@ ) || funcName; } + /** + * Gets the `setBindData` fork from `source`. + * + * @private + * @param {String} source The source to inspect. + * @returns {String} Returns the fork. + */ + function getSetBindDataFork(source) { + var result = matchFunction(source, 'setBindData').match(/!defineProperty[^:]+:\s*/); + return result ? result[0] : ''; + } + /** * Gets the `templateSettings` assignment from `source`. * * @private * @param {String} source The source to inspect. - * @returns {String} Returns the `templateSettings`. + * @returns {String} Returns the assignment. */ function getTemplateSettings(source) { var result = source.match(RegExp( @@ -1473,8 +1489,8 @@ */ function matchFunction(source, funcName, leadingComments) { var result = _.reduce([ - // match variable declarations with `createIterator` and `template` - '( *)var ' + funcName + ' *=.*?(?:createIterator|template)\\((?:.+|[\\s\\S]+?\\n\\3}?)\\);\\n', + // match variable declarations using `createAggregator`, `createIterator` and `template` + '( *)var ' + funcName + ' *=.*?(?:create[A-Z][a-z]+|template)\\((?:.+|[\\s\\S]+?\\n\\3}?)\\);\\n', // match a function declaration '( *)function ' + funcName + '\\b[\\s\\S]+?\\n\\3}\\n', // match a variable declaration with function expression @@ -1490,7 +1506,7 @@ return result && ( /@type +Function\b/.test(result[0]) || - /(?:function(?:\s+\w+)?\b|createIterator|template)\(/.test(result[1])) + /(?:function(?:\s+\w+)?\b|create[A-Z][a-z]+|template)\(/.test(result[1])) ? (leadingComments ? result[0] : '') + result[1] : ''; } @@ -1634,8 +1650,8 @@ // remove `__bindData__` logic and `setBindData` function calls from `_.createCallback` source = source.replace(matchFunction(source, 'createCallback'), function(match) { return match - .replace(/(?:\s*\/\/.*)\n( *)var bindData *=[\s\S]+?\n\1}/, '') - .replace(/(?:\s*\/\/.*)\n( *)if *\(bindData[\s\S]+?\n\1}/, ''); + .replace(/(?:\s*\/\/.*)*\n( *)var bindData *=[\s\S]+?\n\1}/, '') + .replace(/(?:\s*\/\/.*)*\n( *)if *\(bindData[\s\S]+?\n\1}/, ''); }); return source; @@ -1936,6 +1952,19 @@ return source; } + /** + * Removes the `setBindData` fork from `source`. + * + * @private + * @param {String} source The source to process. + * @returns {String} Returns the modified source. + */ + function removeSetBindDataFork(source) { + return source = source.replace(matchFunction(source, 'isArray'), function(match) { + return match.replace(getSetBindDataFork(source), ''); + }); + } + /** * Removes the `support.spliceObjects` fix from the `Array` function mixins * snippet of `source`. @@ -2710,8 +2739,10 @@ }); } else if (isModern) { + funcDependencyMap.setBindData = _.without(funcDependencyMap.setBindData, 'noop'); + _.forOwn(funcDependencyMap, function(deps, funcName) { - if (_.contains(deps, 'isArguments')) { + if (funcName != 'baseFlatten' && _.contains(deps, 'isArguments')) { funcDependencyMap[funcName] = _.without(deps, 'isArguments'); } }); @@ -3004,6 +3035,7 @@ } if (isModern) { source = removeIsArgumentsFork(source); + source = removeSetBindDataFork(source); source = removeSupportSpliceObjects(source); if (isMobile) { diff --git a/build/pre-compile.js b/build/pre-compile.js index 342fda376..00e0b9191 100644 --- a/build/pre-compile.js +++ b/build/pre-compile.js @@ -149,6 +149,7 @@ 'imports', 'include', 'index', + 'indexBy', 'indexOf', 'initial', 'inject', diff --git a/dist/lodash.compat.js b/dist/lodash.compat.js index 1a723b18f..250e8f26c 100644 --- a/dist/lodash.compat.js +++ b/dist/lodash.compat.js @@ -557,12 +557,12 @@ * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`, * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`, - * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`, - * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, - * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, - * `unzip`, `values`, `where`, `without`, `wrap`, and `zip` + * `forOwn`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, + * `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, + * `omit`, `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, + * `range`, `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, and `zip` * * The non-chainable wrapper functions are: * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, @@ -1322,6 +1322,28 @@ return result; } + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + forEach(collection, function(value, key, collection) { + key = String(callback(value, key, collection)); + setter(result, value, key, collection); + }); + return result; + }; + } + /** * Creates a function that, when called, invokes `func` with the `this` binding * of `thisArg` and prepends any `partialArgs` to the arguments passed to the @@ -1489,14 +1511,14 @@ * @param {Function} func The function to set data on. * @param {Mixed} value The value to set. */ - function setBindData(func, value) { + var setBindData = !defineProperty ? noop : function(func, value) { defineProperty(func, '__bindData__', { 'configurable': false, 'enumerable': false, 'value': value, 'writable': false }); - } + }; /** * A fallback implementation of `isPlainObject` which checks if a given `value` @@ -2247,7 +2269,7 @@ * Checks if `value` is `NaN`. * * Note: This is not the same as native `isNaN`, which will return `true` for - * `undefined` and other values. See http://es5.github.io/#x15.1.2.4. + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. * * @static * @memberOf _ @@ -2769,10 +2791,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the given `callback`. The corresponding value of each key - * is the number of times the key was returned by the `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the number of times the key was returned by the `callback`. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -2801,16 +2824,9 @@ * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); /** * Checks if the `callback` returns a truthy value for **all** elements of a @@ -3045,10 +3061,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the `callback`. The corresponding value of each key is - * an array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the `callback`. The corresponding + * value of each key is an array of the elements responsible for generating + * the key. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -3078,16 +3095,52 @@ * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } + /** + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the last element responsible for generating the key. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** * Invokes the method named by `methodName` on each element in the `collection`, @@ -4225,7 +4278,8 @@ /** * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. * * @static * @memberOf _ @@ -4810,6 +4864,7 @@ return result; }; } + // exit early if there is no `thisArg` if (typeof thisArg == 'undefined') { return func; } @@ -4827,9 +4882,7 @@ return func.call(thisArg, accumulator, value, index, collection); }; } - return function() { - return func.apply(thisArg, arguments); - }; + return bind(func, thisArg); } /** @@ -5739,6 +5792,7 @@ lodash.forOwn = forOwn; lodash.functions = functions; lodash.groupBy = groupBy; + lodash.indexBy = indexBy; lodash.initial = initial; lodash.intersection = intersection; lodash.invert = invert; diff --git a/dist/lodash.compat.min.js b/dist/lodash.compat.min.js index 2c0305f17..d15a61979 100644 --- a/dist/lodash.compat.min.js +++ b/dist/lodash.compat.min.js @@ -5,48 +5,47 @@ */ ;!function(n){function t(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++et||typeof n=="undefined")return 1;if(ne?0:e);++r=O&&i===t,v=u||s?l():c;if(s){var h=o(v);h?(i=e,v=h):(s=b,v=u?v:(p(v),c))}for(;++ai(v,y))&&((u||s)&&v.push(y),c.push(h))}return s?(p(v.b),g(v)):u&&p(v),c}function ut(n,t,e,r,u,a){var o=a&&!u;if(!vt(n)&&!o)throw new Yt;if(u||a||r.length||!(Pe.fastBind||me&&e.length))i=function(){var a=arguments,f=u?this:t; -return o&&(n=t[l]),(e.length||r.length)&&(ye.apply(a,e),se.apply(a,r)),this instanceof i?(f=ot(n.prototype),a=n.apply(f,a),ht(a)?a:f):n.apply(f,a)};else{a=[n,t],se.apply(a,e);var i=me.call.apply(me,a)}if(o){var l=t;t=n}return i}function at(){var n=f();n.h=q,n.b=n.c=n.g=n.i="",n.e="s",n.j=m;for(var t,e=0;t=arguments[e];e++)for(var r in t)n[r]=t[r];e=n.a,n.d=/^[^,]+/.exec(e)[0],t=Mt,e="return function("+e+"){",r="var m,s="+n.d+",D="+n.e+";if(!s)return D;"+n.i+";",n.b?(r+="var t=s.length;m=-1;if("+n.b+"){",Pe.unindexedChars&&(r+="if(r(s)){s=s.split('')}"),r+="while(++me?0:e);++r=O&&i===t,v=u||s?l():c;if(s){var h=o(v);h?(i=e,v=h):(s=b,v=u?v:(p(v),c))}for(;++ai(v,y))&&((u||s)&&v.push(y),c.push(h))}return s?(p(v.b),g(v)):u&&p(v),c}function ut(n){return function(t,e,r){var u={};return e=_.createCallback(e,r,3),kt(t,function(t,r,a){r=Yt(e(t,r,a)),n(u,t,r,a)}),u}}function at(n,t,e,r,u,a){var o=a&&!u; +if(!ht(n)&&!o)throw new Zt;if(u||a||r.length||!(Pe.fastBind||de&&e.length))i=function(){var a=arguments,f=u?this:t;return o&&(n=t[l]),(e.length||r.length)&&(me.apply(a,e),pe.apply(a,r)),this instanceof i?(f=it(n.prototype),a=n.apply(f,a),yt(a)?a:f):n.apply(f,a)};else{a=[n,t],pe.apply(a,e);var i=de.call.apply(de,a)}if(o){var l=t;t=n}return i}function ot(){var n=f();n.h=q,n.b=n.c=n.g=n.i="",n.e="s",n.j=m;for(var t,e=0;t=arguments[e];e++)for(var r in t)n[r]=t[r];e=n.a,n.d=/^[^,]+/.exec(e)[0],t=Gt,e="return function("+e+"){",r="var m,s="+n.d+",D="+n.e+";if(!s)return D;"+n.i+";",n.b?(r+="var t=s.length;m=-1;if("+n.b+"){",Pe.unindexedChars&&(r+="if(r(s)){s=s.split('')}"),r+="while(++mk;k++)r+="m='"+n.h[k]+"';if((!(q&&w[m])&&l.call(s,m))",n.j||(r+="||(!w[m]&&s[m]!==z[m])"),r+="){"+n.g+"}"; -r+="}"}return(n.b||Pe.nonEnumArgs)&&(r+="}"),r+=n.c+";return D",t=t("i,j,l,n,o,p,r,u,v,z,A,x,H,I,K",e+r+"}"),g(n),t(J,ne,ce,C,st,Be,mt,n.f,_,te,X,Ie,V,ee,he)}function ot(n){return ht(n)?de(n):{}}function it(n){return qe[n]}function lt(){var n=(n=_.indexOf)===It?t:n;return n}function ft(n){var t,e;return!n||he.call(n)!=G||(t=n.constructor,vt(t)&&!(t instanceof t))||!Pe.argsClass&&st(n)||!Pe.nodeClass&&c(n)?b:Pe.ownLast?(Me(n,function(n,t,r){return e=ce.call(r,t),b}),e!==false):(Me(n,function(n,t){e=t -}),e===y||ce.call(n,e))}function ct(n){return Te[n]}function st(n){return n&&typeof n=="object"?he.call(n)==T:b}function pt(n){var t=[];return Me(n,function(n,e){vt(n)&&t.push(e)}),t.sort()}function gt(n){for(var t=-1,e=Fe(n),r=e.length,u={};++te?Ce(0,a+e):e)||0,a&&typeof a=="number"?o=-1<(mt(n)?n.indexOf(t,e):u(n,t,e)):Le(n,function(n){return++ra&&(a=i)}}else t=!t&&mt(n)?u:_.createCallback(t,e,3),Le(n,function(n,e,u){e=t(n,e,u),e>r&&(r=e,a=n)});return a}function Ot(n,t,e,r){var u=3>arguments.length;if(t=_.createCallback(t,r,4),Be(n)){var a=-1,o=n.length;for(u&&(e=n[++a]);++aarguments.length; -if(typeof a!="number")var i=Fe(n),a=i.length;else Pe.unindexedChars&&mt(n)&&(u=n.split(""));return t=_.createCallback(t,r,4),Ct(n,function(n,r,l){r=i?i[--a]:--a,e=o?(o=b,u[r]):t(e,u[r],r,l)}),e}function St(n,t,e){var r;if(t=_.createCallback(t,e,3),Be(n)){e=-1;for(var u=n.length;++e=O&&u===t;if(f){var c=o(i);c?(u=e,i=c):f=b}for(;++ru(i,c)&&l.push(c); -return f&&g(i),l}function Dt(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=d){var a=-1;for(t=_.createCallback(t,e,3);++ar?Ce(0,u+r):r||0}else if(r)return r=Bt(n,e),n[r]===e?r:-1;return n?t(n,e,r):-1}function Pt(n,t,e){if(typeof t!="number"&&t!=d){var r=0,u=-1,a=n?n.length:0;for(t=_.createCallback(t,e,3);++u>>1,e(n[r])e?0:e);++tf&&(i=n.apply(l,o));else{var e=new Ht; -!p&&!h&&(c=e);var r=s-(e-c);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:_}},de||(ot=function(n){if(ht(n)){s.prototype=n;var t=new s;s.prototype=d}return t||{}}),Pe.argsClass||(st=function(n){return n&&typeof n=="object"?ce.call(n,"callee"):b});var Be=be||function(n){return n&&typeof n=="object"?he.call(n)==W:b},Ne=at({a:"y",e:"[]",i:"if(!(A[typeof y]))return D",g:"D.push(m)"}),Fe=we?function(n){return ht(n)?Pe.enumPrototypes&&typeof n=="function"||Pe.nonEnumArgs&&n.length&&st(n)?Ne(n):we(n):[] -}:Ne,$e={a:"f,d,J",i:"d=d&&typeof J=='undefined'?d:v.createCallback(d,J,3)",b:"typeof t=='number'",u:Fe,g:"if(d(s[m],m,f)===false)return D"},ze={a:"y,G,k",i:"var a=arguments,b=0,c=typeof k=='number'?2:a.length;while(++b":">",'"':""","'":"'"},Te=gt(qe),We=Qt("("+Fe(Te).join("|")+")","g"),Ke=Qt("["+Fe(qe).join("")+"]","g"),Le=at($e),Je=at(ze,{i:ze.i.replace(";",";if(c>3&&typeof a[c-2]=='function'){var d=v.createCallback(a[--c-1],a[c--],2)}else if(c>2&&typeof a[c-1]=='function'){d=a[--c]}"),g:"D[m]=d?d(D[m],s[m]):s[m]"}),He=at(ze),Me=at($e,Re,{j:b}),Ge=at($e,Re); -vt(/x/)&&(vt=function(n){return typeof n=="function"&&he.call(n)==H});var Ue=fe?function(n){if(!n||he.call(n)!=G||!Pe.argsClass&&st(n))return b;var t=n.valueOf,e=typeof t=="function"&&(e=fe(t))&&fe(e);return e?n==e||fe(n)==e:ft(n)}:ft,Ve=kt;Ae&&nt&&typeof ge=="function"&&(qt=zt(ge,r));var Qe=8==xe(S+"08")?xe:function(n,t){return xe(mt(n)?n.replace(F,""):n,t||0)};return _.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},_.assign=Je,_.at=function(n){var t=-1,e=Y(arguments,m,b,1),r=e.length,u=Lt(r); -for(Pe.unindexedChars&&mt(n)&&(n=n.split(""));++t=O&&o(a?r[a]:h)}n:for(;++f(m?e(m,y):c(h,y))){for(a=u,(m||h).push(y);--a;)if(m=i[a],0>(m?e(m,y):c(r[a],y)))continue n;v.push(y)}}for(;u--;)(m=i[u])&&g(m);return p(i),p(h),v},_.invert=gt,_.invoke=function(n,t){var e=Ee.call(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Lt(typeof a=="number"?a:0);return Ct(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},_.keys=Fe,_.map=kt,_.max=xt,_.memoize=function(n,t){function e(){var r=e.cache,u=x+(t?t.apply(this,arguments):arguments[0]); -return ce.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}return e.cache={},e},_.merge=function(n){var t=arguments,e=2;if(!ht(n))return n;if("number"!=typeof t[2]&&(e=t.length),3r(o,e))&&(a[e]=n)}),a},_.once=function(n){var t,e;return function(){return t?e:(t=m,e=n.apply(this,arguments),n=d,e)}},_.pairs=function(n){for(var t=-1,e=Fe(n),r=e.length,u=Lt(r);++te?Ce(0,r+e):ke(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},_.mixin=Wt,_.noConflict=function(){return r._=re,this},_.parseInt=Qe,_.random=function(n,t){n==d&&t==d&&(t=1),n=+n||0,t==d?(t=n,n=0):t=+t||0;var e=Oe(); -return n%1||t%1?n+ke(e*(t-n+parseFloat("1e-"+((e+"").length-1))),t):n+le(e*(t-n+1))},_.reduce=Ot,_.reduceRight=Et,_.result=function(n,t){var e=n?n[t]:y;return vt(e)?n[t]():e},_.runInContext=h,_.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Fe(n).length},_.some=St,_.sortedIndex=Bt,_.template=function(n,t,e){var r=_.templateSettings;n||(n=""),e=He({},e,r);var u,a=He({},e.imports,r.imports),r=Fe(a),a=dt(a),o=0,l=e.interpolate||$,f="__p+='",l=Qt((e.escape||$).source+"|"+l.source+"|"+(l===N?P:$).source+"|"+(e.evaluate||$).source+"|$","g"); -n.replace(l,function(t,e,r,a,l,c){return r||(r=a),f+=n.slice(o,c).replace(z,i),e&&(f+="'+__e("+e+")+'"),l&&(u=m,f+="';"+l+";__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),o=c+t.length,t}),f+="';\n",l=e=e.variable,l||(e="obj",f="with("+e+"){"+f+"}"),f=(u?f.replace(A,""):f).replace(D,"$1").replace(I,"$1;"),f="function("+e+"){"+(l?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var c=Mt(r,"return "+f).apply(y,a) -}catch(s){throw s.source=f,s}return t?c(t):(c.source=f,c)},_.unescape=function(n){return n==d?"":Xt(n).replace(We,ct)},_.uniqueId=function(n){var t=++w;return Xt(n==d?"":n)+t},_.all=_t,_.any=St,_.detect=wt,_.findWhere=wt,_.foldl=Ot,_.foldr=Et,_.include=bt,_.inject=Ot,Ge(_,function(n,t){_.prototype[t]||(_.prototype[t]=function(){var t=[this.__wrapped__];return se.apply(t,arguments),n.apply(_,t)})}),_.first=Dt,_.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=d){var a=u;for(t=_.createCallback(t,e,3);a--&&t(n[a],a,n);)r++ -}else if(r=t,r==d||e)return n[u-1];return v(n,Ce(0,u-r))}},_.take=Dt,_.head=Dt,Ge(_,function(n,t){_.prototype[t]||(_.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e);return t==d||e&&typeof t!="function"?r:new j(r)})}),_.VERSION="1.3.1",_.prototype.toString=function(){return Xt(this.__wrapped__)},_.prototype.value=Kt,_.prototype.valueOf=Kt,Le(["join","pop","shift"],function(n){var t=Zt[n];_.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)}}),Le(["push","reverse","sort","unshift"],function(n){var t=Zt[n]; -_.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),Le(["concat","slice","splice"],function(n){var t=Zt[n];_.prototype[n]=function(){return new j(t.apply(this.__wrapped__,arguments))}}),Pe.spliceObjects||Le(["pop","shift","splice"],function(n){var t=Zt[n],e="splice"==n;_.prototype[n]=function(){var n=this.__wrapped__,r=t.apply(n,arguments);return 0===n.length&&delete n[0],e?new j(r):r}}),_}var y,m=!0,d=null,b=!1,_=[],j=[],w=0,C={},x=+new Date+"",O=75,E=40,S=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",A=/\b__p\+='';/g,D=/\b(__p\+=)''\+/g,I=/(__e\(.*?\)|\b__t\))\+'';/g,P=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,B=/\w*$/,N=/<%=([\s\S]+?)%>/g,F=RegExp("^["+S+"]*0+(?=.$)"),$=/($^)/,z=/['\n\r\t\u2028\u2029\\]/g,R="Array Boolean Date Error Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),q="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="[object Arguments]",W="[object Array]",K="[object Boolean]",L="[object Date]",J="[object Error]",H="[object Function]",M="[object Number]",G="[object Object]",U="[object RegExp]",V="[object String]",Q={}; +r+="}"}return(n.b||Pe.nonEnumArgs)&&(r+="}"),r+=n.c+";return D",t=t("i,j,l,n,o,p,r,u,v,z,A,x,H,I,K",e+r+"}"),g(n),t(J,te,se,C,pt,Ne,dt,n.f,_,ee,X,Be,V,re,ye)}function it(n){return yt(n)?be(n):{}}function lt(n){return Te[n]}function ft(){var n=(n=_.indexOf)===Bt?t:n;return n}function ct(n){var t,e;return!n||ye.call(n)!=G||(t=n.constructor,ht(t)&&!(t instanceof t))||!Pe.argsClass&&pt(n)||!Pe.nodeClass&&c(n)?b:Pe.ownLast?(Ge(n,function(n,t,r){return e=se.call(r,t),b}),e!==false):(Ge(n,function(n,t){e=t +}),e===y||se.call(n,e))}function st(n){return We[n]}function pt(n){return n&&typeof n=="object"?ye.call(n)==T:b}function gt(n){var t=[];return Ge(n,function(n,e){ht(n)&&t.push(e)}),t.sort()}function vt(n){for(var t=-1,e=$e(n),r=e.length,u={};++te?ke(0,a+e):e)||0,a&&typeof a=="number"?o=-1<(dt(n)?n.indexOf(t,e):u(n,t,e)):Je(n,function(n){return++ra&&(a=i)}}else t=!t&&dt(n)?u:_.createCallback(t,e,3),Je(n,function(n,e,u){e=t(n,e,u),e>r&&(r=e,a=n)});return a}function Et(n,t,e,r){var u=3>arguments.length;if(t=_.createCallback(t,r,4),Ne(n)){var a=-1,o=n.length;for(u&&(e=n[++a]);++aarguments.length; +if(typeof a!="number")var i=$e(n),a=i.length;else Pe.unindexedChars&&dt(n)&&(u=n.split(""));return t=_.createCallback(t,r,4),kt(n,function(n,r,l){r=i?i[--a]:--a,e=o?(o=b,u[r]):t(e,u[r],r,l)}),e}function At(n,t,e){var r;if(t=_.createCallback(t,e,3),Ne(n)){e=-1;for(var u=n.length;++e=O&&u===t;if(f){var c=o(i);c?(u=e,i=c):f=b}for(;++ru(i,c)&&l.push(c); +return f&&g(i),l}function It(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=d){var a=-1;for(t=_.createCallback(t,e,3);++ar?ke(0,u+r):r||0}else if(r)return r=Nt(n,e),n[r]===e?r:-1;return n?t(n,e,r):-1}function Pt(n,t,e){if(typeof t!="number"&&t!=d){var r=0,u=-1,a=n?n.length:0;for(t=_.createCallback(t,e,3);++u>>1,e(n[r])e?0:e);++tf&&(i=n.apply(l,o));else{var e=new Mt; +!p&&!h&&(c=e);var r=s-(e-c);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:_}},be||(it=function(n){if(yt(n)){s.prototype=n;var t=new s;s.prototype=d}return t||{}}),Pe.argsClass||(pt=function(n){return n&&typeof n=="object"?se.call(n,"callee"):b});var Ne=_e||function(n){return n&&typeof n=="object"?ye.call(n)==W:b},Fe=ot({a:"y",e:"[]",i:"if(!(A[typeof y]))return D",g:"D.push(m)"}),$e=Ce?function(n){return yt(n)?Pe.enumPrototypes&&typeof n=="function"||Pe.nonEnumArgs&&n.length&&pt(n)?Fe(n):Ce(n):[] +}:Fe,ze={a:"f,d,J",i:"d=d&&typeof J=='undefined'?d:v.createCallback(d,J,3)",b:"typeof t=='number'",u:$e,g:"if(d(s[m],m,f)===false)return D"},Re={a:"y,G,k",i:"var a=arguments,b=0,c=typeof k=='number'?2:a.length;while(++b":">",'"':""","'":"'"},We=vt(Te),Ke=Xt("("+$e(We).join("|")+")","g"),Le=Xt("["+$e(Te).join("")+"]","g"),Je=ot(ze),He=ot(Re,{i:Re.i.replace(";",";if(c>3&&typeof a[c-2]=='function'){var d=v.createCallback(a[--c-1],a[c--],2)}else if(c>2&&typeof a[c-1]=='function'){d=a[--c]}"),g:"D[m]=d?d(D[m],s[m]):s[m]"}),Me=ot(Re),Ge=ot(ze,qe,{j:b}),Ue=ot(ze,qe); +ht(/x/)&&(ht=function(n){return typeof n=="function"&&ye.call(n)==H});var Ve=ce?function(n){if(!n||ye.call(n)!=G||!Pe.argsClass&&pt(n))return b;var t=n.valueOf,e=typeof t=="function"&&(e=ce(t))&&ce(e);return e?n==e||ce(n)==e:ct(n)}:ct,Qe=ut(function(n,t,e){se.call(n,e)?n[e]++:n[e]=1}),Xe=ut(function(n,t,e){(se.call(n,e)?n[e]:n[e]=[]).push(t)}),Ye=ut(function(n,t,e){n[e]=t}),Ze=xt;De&&nt&&typeof ve=="function"&&(Tt=Rt(ve,r));var nr=8==Oe(S+"08")?Oe:function(n,t){return Oe(dt(n)?n.replace(F,""):n,t||0) +};return _.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},_.assign=He,_.at=function(n){var t=-1,e=Y(arguments,m,b,1),r=e.length,u=Jt(r);for(Pe.unindexedChars&&dt(n)&&(n=n.split(""));++t=O&&o(a?r[a]:h)}n:for(;++f(m?e(m,y):c(h,y))){for(a=u,(m||h).push(y);--a;)if(m=i[a],0>(m?e(m,y):c(r[a],y)))continue n; +v.push(y)}}for(;u--;)(m=i[u])&&g(m);return p(i),p(h),v},_.invert=vt,_.invoke=function(n,t){var e=Se.call(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Jt(typeof a=="number"?a:0);return kt(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},_.keys=$e,_.map=xt,_.max=Ot,_.memoize=function(n,t){function e(){var r=e.cache,u=x+(t?t.apply(this,arguments):arguments[0]);return se.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}return e.cache={},e},_.merge=function(n){var t=arguments,e=2;if(!yt(n))return n; +if("number"!=typeof t[2]&&(e=t.length),3r(o,e))&&(a[e]=n)}),a},_.once=function(n){var t,e;return function(){return t?e:(t=m,e=n.apply(this,arguments),n=d,e)}},_.pairs=function(n){for(var t=-1,e=$e(n),r=e.length,u=Jt(r);++te?ke(0,r+e):xe(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},_.mixin=Kt,_.noConflict=function(){return r._=ue,this +},_.parseInt=nr,_.random=function(n,t){n==d&&t==d&&(t=1),n=+n||0,t==d?(t=n,n=0):t=+t||0;var e=Ee();return n%1||t%1?n+xe(e*(t-n+parseFloat("1e-"+((e+"").length-1))),t):n+fe(e*(t-n+1))},_.reduce=Et,_.reduceRight=St,_.result=function(n,t){var e=n?n[t]:y;return ht(e)?n[t]():e},_.runInContext=h,_.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:$e(n).length},_.some=At,_.sortedIndex=Nt,_.template=function(n,t,e){var r=_.templateSettings;n||(n=""),e=Me({},e,r);var u,a=Me({},e.imports,r.imports),r=$e(a),a=bt(a),o=0,l=e.interpolate||$,f="__p+='",l=Xt((e.escape||$).source+"|"+l.source+"|"+(l===N?B:$).source+"|"+(e.evaluate||$).source+"|$","g"); +n.replace(l,function(t,e,r,a,l,c){return r||(r=a),f+=n.slice(o,c).replace(z,i),e&&(f+="'+__e("+e+")+'"),l&&(u=m,f+="';"+l+";__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),o=c+t.length,t}),f+="';\n",l=e=e.variable,l||(e="obj",f="with("+e+"){"+f+"}"),f=(u?f.replace(A,""):f).replace(D,"$1").replace(I,"$1;"),f="function("+e+"){"+(l?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var c=Gt(r,"return "+f).apply(y,a) +}catch(s){throw s.source=f,s}return t?c(t):(c.source=f,c)},_.unescape=function(n){return n==d?"":Yt(n).replace(Ke,st)},_.uniqueId=function(n){var t=++w;return Yt(n==d?"":n)+t},_.all=jt,_.any=At,_.detect=Ct,_.findWhere=Ct,_.foldl=Et,_.foldr=St,_.include=_t,_.inject=Et,Ue(_,function(n,t){_.prototype[t]||(_.prototype[t]=function(){var t=[this.__wrapped__];return pe.apply(t,arguments),n.apply(_,t)})}),_.first=It,_.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=d){var a=u;for(t=_.createCallback(t,e,3);a--&&t(n[a],a,n);)r++ +}else if(r=t,r==d||e)return n[u-1];return v(n,ke(0,u-r))}},_.take=It,_.head=It,Ue(_,function(n,t){_.prototype[t]||(_.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e);return t==d||e&&typeof t!="function"?r:new j(r)})}),_.VERSION="1.3.1",_.prototype.toString=function(){return Yt(this.__wrapped__)},_.prototype.value=Lt,_.prototype.valueOf=Lt,Je(["join","pop","shift"],function(n){var t=ne[n];_.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)}}),Je(["push","reverse","sort","unshift"],function(n){var t=ne[n]; +_.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),Je(["concat","slice","splice"],function(n){var t=ne[n];_.prototype[n]=function(){return new j(t.apply(this.__wrapped__,arguments))}}),Pe.spliceObjects||Je(["pop","shift","splice"],function(n){var t=ne[n],e="splice"==n;_.prototype[n]=function(){var n=this.__wrapped__,r=t.apply(n,arguments);return 0===n.length&&delete n[0],e?new j(r):r}}),_}var y,m=!0,d=null,b=!1,_=[],j=[],w=0,C={},x=+new Date+"",O=75,E=40,S=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",A=/\b__p\+='';/g,D=/\b(__p\+=)''\+/g,I=/(__e\(.*?\)|\b__t\))\+'';/g,B=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,P=/\w*$/,N=/<%=([\s\S]+?)%>/g,F=RegExp("^["+S+"]*0+(?=.$)"),$=/($^)/,z=/['\n\r\t\u2028\u2029\\]/g,R="Array Boolean Date Error Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),q="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="[object Arguments]",W="[object Array]",K="[object Boolean]",L="[object Date]",J="[object Error]",H="[object Function]",M="[object Number]",G="[object Object]",U="[object RegExp]",V="[object String]",Q={}; Q[H]=b,Q[T]=Q[W]=Q[K]=Q[L]=Q[M]=Q[G]=Q[U]=Q[V]=m;var X={"boolean":b,"function":m,object:m,number:b,string:b,undefined:b},Y={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},Z=X[typeof exports]&&exports,nt=X[typeof module]&&module&&module.exports==Z&&module,tt=X[typeof global]&&global;!tt||tt.global!==tt&&tt.window!==tt||(n=tt);var et=h();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=et, define(function(){return et})):Z&&!Z.nodeType?nt?(nt.exports=et)._=et:Z._=et:n._=et }(this); \ No newline at end of file diff --git a/dist/lodash.js b/dist/lodash.js index a31d7e440..6bacaf9af 100644 --- a/dist/lodash.js +++ b/dist/lodash.js @@ -506,12 +506,12 @@ * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`, * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`, - * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`, - * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, - * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, - * `unzip`, `values`, `where`, `without`, `wrap`, and `zip` + * `forOwn`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, + * `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, + * `omit`, `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, + * `range`, `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, and `zip` * * The non-chainable wrapper functions are: * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, @@ -1056,6 +1056,28 @@ return result; } + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + forEach(collection, function(value, key, collection) { + key = String(callback(value, key, collection)); + setter(result, value, key, collection); + }); + return result; + }; + } + /** * Creates a function that, when called, invokes `func` with the `this` binding * of `thisArg` and prepends any `partialArgs` to the arguments passed to the @@ -1176,14 +1198,14 @@ * @param {Function} func The function to set data on. * @param {Mixed} value The value to set. */ - function setBindData(func, value) { + var setBindData = !defineProperty ? noop : function(func, value) { defineProperty(func, '__bindData__', { 'configurable': false, 'enumerable': false, 'value': value, 'writable': false }); - } + }; /** * A fallback implementation of `isPlainObject` which checks if a given `value` @@ -1917,7 +1939,7 @@ * Checks if `value` is `NaN`. * * Note: This is not the same as native `isNaN`, which will return `true` for - * `undefined` and other values. See http://es5.github.io/#x15.1.2.4. + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. * * @static * @memberOf _ @@ -2436,10 +2458,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the given `callback`. The corresponding value of each key - * is the number of times the key was returned by the `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the number of times the key was returned by the `callback`. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -2468,16 +2491,9 @@ * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); /** * Checks if the `callback` returns a truthy value for **all** elements of a @@ -2713,10 +2729,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the `callback`. The corresponding value of each key is - * an array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the `callback`. The corresponding + * value of each key is an array of the elements responsible for generating + * the key. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -2746,16 +2763,52 @@ * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } + /** + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the last element responsible for generating the key. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** * Invokes the method named by `methodName` on each element in the `collection`, @@ -3902,7 +3955,8 @@ /** * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. * * @static * @memberOf _ @@ -4487,20 +4541,20 @@ return result; }; } - var bindData = func.__bindData__; + // exit early if there is no `thisArg` + if (typeof thisArg == 'undefined') { + return func; + } + var bindData = !func.name || func.__bindData__; if (typeof bindData == 'undefined') { // checks if `func` references the `this` keyword and stores the result bindData = !reThis || reThis.test(fnToString.call(func)); setBindData(func, bindData); } - if (typeof thisArg == 'undefined' || !bindData) { + // exit early if there are no `this` references or `func` is bound + if (bindData !== true && !(bindData && bindData[4])) { return func; } - else if (bindData !== true) { - // exit early if already bound or leverage bind optimizations if - // created by `_.partial` or `_.partialRight` - return bindData[4] ? bind(func, thisArg) : func; - } switch (argCount) { case 1: return function(value) { return func.call(thisArg, value); @@ -4515,9 +4569,7 @@ return func.call(thisArg, accumulator, value, index, collection); }; } - return function() { - return func.apply(thisArg, arguments); - }; + return bind(func, thisArg); } /** @@ -5427,6 +5479,7 @@ lodash.forOwn = forOwn; lodash.functions = functions; lodash.groupBy = groupBy; + lodash.indexBy = indexBy; lodash.initial = initial; lodash.intersection = intersection; lodash.invert = invert; diff --git a/dist/lodash.min.js b/dist/lodash.min.js index 2b5c450d2..6e888a5bb 100644 --- a/dist/lodash.min.js +++ b/dist/lodash.min.js @@ -3,46 +3,46 @@ * Lo-Dash 1.3.1 (Custom Build) lodash.com/license | Underscore.js 1.5.1 underscorejs.org/LICENSE * Build: `lodash modern -o ./dist/lodash.js` */ -;!function(n){function t(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++et||typeof n=="undefined")return 1;if(ne?0:e);++r=j&&i===t,g=u||v?f():s;if(v){var y=o(g);y?(i=e,g=y):(v=b,g=u?g:(c(g),s))}for(;++ai(g,h))&&((u||v)&&g.push(h),s.push(y))}return v?(c(g.b),p(g)):u&&c(g),s}function at(n,t,e,r,u,a){var o=a&&!u;if(!gt(n)&&!o)throw new Zt;var i=n.__bindData__;if(i)return pe.apply(i[2],e),pe.apply(i[3],r),!u&&i[4]&&(i[1]=t,i[4]=b,i[5]=a),at.apply(h,i);if(u||a||r.length||!(Ie.fastBind||he&&e.length))f=function(){var a=arguments,i=u?this:t; -return o&&(n=t[l]),(e.length||r.length)&&(ye.apply(a,e),pe.apply(a,r)),this instanceof f?(i=yt(n.prototype)?be(n.prototype):{},a=n.apply(i,a),yt(a)?a:i):n.apply(i,a)};else{i=[n,t],pe.apply(i,e);var f=he.call.apply(he,i)}if(i=Oe.call(arguments),o){var l=t;t=n}return ft(f,i),f}function ot(n){return Be[n]}function it(){var n=(n=Y.indexOf)===$t?t:n;return n}function ft(n,t){oe(n,"__bindData__",{configurable:b,enumerable:b,value:t,writable:b})}function lt(n){var t,e;return n&&ge.call(n)==K&&(t=n.constructor,!gt(t)||t instanceof t)?(w(n,function(n,t){e=t -}),e===g||ce.call(n,e)):b}function ct(n){return De[n]}function pt(n){return n&&typeof n=="object"?ge.call(n)==R:b}function st(n){var t=[];return w(n,function(n,e){gt(n)&&t.push(e)}),t.sort()}function vt(n){for(var t=-1,e=$e(n),r=e.length,u={};++te?je(0,a+e):e)||0,a&&typeof a=="number"?o=-1<(bt(n)?n.indexOf(t,e):u(n,t,e)):d(n,function(n){return++ra&&(a=i)}}else t=!t&&bt(n)?u:Y.createCallback(t,e,3),wt(n,function(n,e,u){e=t(n,e,u),e>r&&(r=e,a=n)});return a}function Ot(n,t){var e=-1,r=n?n.length:0;if(typeof r=="number")for(var u=Ut(r);++earguments.length;t=Y.createCallback(t,r,4);var a=-1,o=n.length;if(typeof o=="number")for(u&&(e=n[++a]);++aarguments.length;if(typeof u!="number")var o=$e(n),u=o.length;return t=Y.createCallback(t,r,4),wt(n,function(r,i,f){i=o?o[--u]:--u,e=a?(a=b,n[i]):t(e,n[i],i,f)}),e}function At(n,t,e){var r;t=Y.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e=j&&u===t; -if(l){var c=o(i);c?(u=e,i=c):l=b}for(;++ru(i,c)&&f.push(c);return l&&p(i),f}function Nt(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=h){var a=-1;for(t=Y.createCallback(t,e,3);++ar?je(0,u+r):r||0}else if(r)return r=Dt(n,e),n[r]===e?r:-1;return n?t(n,e,r):-1}function Bt(n,t,e){if(typeof t!="number"&&t!=h){var r=0,u=-1,a=n?n.length:0; -for(t=Y.createCallback(t,e,3);++u>>1,e(n[r])e?0:e);++tl&&(i=n.apply(f,o)); -else{var e=new Gt;!s&&!m&&(c=e);var r=p-(e-c);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:I,variable:"",imports:{_:Y}};var Ne=me,$e=ke?function(n){return yt(n)?ke(n):[]}:Q,Be={"&":"&","<":"<",">":">",'"':""","'":"'"},De=vt(Be),Fe=Xt("("+$e(De).join("|")+")","g"),Re=Xt("["+$e(Be).join("")+"]","g");Se&&L&&typeof se=="function"&&(Wt=qt(se,r));var Te=8==Ce(C+"08")?Ce:function(n,t){return Ce(bt(n)?n.replace(N,""):n,t||0) -};return Y.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},Y.assign=J,Y.at=function(n){for(var t=-1,e=tt(arguments,y,b,1),r=e.length,u=Ut(r);++t=j&&o(a?r[a]:y)}n:for(;++l(b?e(b,h):s(y,h))){for(a=u,(b||y).push(h);--a;)if(b=i[a],0>(b?e(b,h):s(r[a],h)))continue n;g.push(h)}}for(;u--;)(b=i[u])&&p(b);return c(i),c(y),g},Y.invert=vt,Y.invoke=function(n,t){var e=Oe.call(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Ut(typeof a=="number"?a:0); -return wt(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},Y.keys=$e,Y.map=Ct,Y.max=xt,Y.memoize=function(n,t){function e(){var r=e.cache,u=k+(t?t.apply(this,arguments):arguments[0]);return ce.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}return e.cache={},e},Y.merge=function(n){var t=arguments,e=2;if(!yt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3r(o,e))&&(a[e]=n)}),a},Y.once=function(n){var t,e;return function(){return t?e:(t=y,e=n.apply(this,arguments),n=h,e) -}},Y.pairs=function(n){for(var t=-1,e=$e(n),r=e.length,u=Ut(r);++te?je(0,r+e):we(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},Y.mixin=Kt,Y.noConflict=function(){return r._=ee,this},Y.parseInt=Te,Y.random=function(n,t){n==h&&t==h&&(t=1),n=+n||0,t==h?(t=n,n=0):t=+t||0;var e=xe();return n%1||t%1?n+we(e*(t-n+parseFloat("1e-"+((e+"").length-1))),t):n+ie(e*(t-n+1)) -},Y.reduce=Et,Y.reduceRight=St,Y.result=function(n,t){var e=n?n[t]:g;return gt(e)?n[t]():e},Y.runInContext=v,Y.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:$e(n).length},Y.some=At,Y.sortedIndex=Dt,Y.template=function(n,t,e){var r=Y.templateSettings;n||(n=""),e=H({},e,r);var u,a=H({},e.imports,r.imports),r=$e(a),a=mt(a),o=0,f=e.interpolate||$,l="__p+='",f=Xt((e.escape||$).source+"|"+f.source+"|"+(f===I?S:$).source+"|"+(e.evaluate||$).source+"|$","g");n.replace(f,function(t,e,r,a,f,c){return r||(r=a),l+=n.slice(o,c).replace(D,i),e&&(l+="'+__e("+e+")+'"),f&&(u=y,l+="';"+f+";__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),o=c+t.length,t -}),l+="';\n",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(x,""):l).replace(O,"$1").replace(E,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=Ht(r,"return "+l).apply(g,a)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},Y.unescape=function(n){return n==h?"":Yt(n).replace(Fe,ct)},Y.uniqueId=function(n){var t=++_;return Yt(n==h?"":n)+t -},Y.all=_t,Y.any=At,Y.detect=jt,Y.findWhere=jt,Y.foldl=Et,Y.foldr=St,Y.include=dt,Y.inject=Et,d(Y,function(n,t){Y.prototype[t]||(Y.prototype[t]=function(){var t=[this.__wrapped__];return pe.apply(t,arguments),n.apply(Y,t)})}),Y.first=Nt,Y.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=h){var a=u;for(t=Y.createCallback(t,e,3);a--&&t(n[a],a,n);)r++}else if(r=t,r==h||e)return n[u-1];return s(n,je(0,u-r))}},Y.take=Nt,Y.head=Nt,d(Y,function(n,t){Y.prototype[t]||(Y.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e); -return t==h||e&&typeof t!="function"?r:new Z(r)})}),Y.VERSION="1.3.1",Y.prototype.toString=function(){return Yt(this.__wrapped__)},Y.prototype.value=Mt,Y.prototype.valueOf=Mt,wt(["join","pop","shift"],function(n){var t=ne[n];Y.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)}}),wt(["push","reverse","sort","unshift"],function(n){var t=ne[n];Y.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),wt(["concat","slice","splice"],function(n){var t=ne[n];Y.prototype[n]=function(){return new Z(t.apply(this.__wrapped__,arguments)) -}}),Y}var g,y=!0,h=null,b=!1,m=[],d=[],_=0,k=+new Date+"",j=75,w=40,C=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",x=/\b__p\+='';/g,O=/\b(__p\+=)''\+/g,E=/(__e\(.*?\)|\b__t\))\+'';/g,S=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,A=/\w*$/,I=/<%=([\s\S]+?)%>/g,N=RegExp("^["+C+"]*0+(?=.$)"),$=/($^)/,B=(B=/\bthis\b/)&&B.test(v)&&B,D=/['\n\r\t\u2028\u2029\\]/g,F="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),R="[object Arguments]",T="[object Array]",q="[object Boolean]",z="[object Date]",W="[object Function]",P="[object Number]",K="[object Object]",M="[object RegExp]",U="[object String]",V={}; -V[W]=b,V[R]=V[T]=V[q]=V[z]=V[P]=V[K]=V[M]=V[U]=y;var G={"boolean":b,"function":y,object:y,number:b,string:b,undefined:b},H={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},J=G[typeof exports]&&exports,L=G[typeof module]&&module&&module.exports==J&&module,Q=G[typeof global]&&global;!Q||Q.global!==Q&&Q.window!==Q||(n=Q);var X=v();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=X, define(function(){return X})):J&&!J.nodeType?L?(L.exports=X)._=X:J._=X:n._=X +;!function(n){function t(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++et||typeof n=="undefined")return 1;if(ne?0:e);++r=w&&i===t,g=u||v?f():c;if(v){var y=o(g);y?(i=e,g=y):(v=m,g=u?g:(p(g),c))}for(;++ai(g,h))&&((u||v)&&g.push(h),c.push(y))}return v?(p(g.b),s(g)):u&&p(g),c}function ot(n){return function(t,e,r){var u={};return e=Z.createCallback(e,r,3),Ct(t,function(t,r,a){r=Zt(e(t,r,a)),n(u,t,r,a)}),u}}function it(n,t,e,r,u,a){var o=a&&!u;if(!yt(n)&&!o)throw new ne;var i=n.__bindData__;if(i)return se.apply(i[2],e),se.apply(i[3],r),!u&&i[4]&&(i[1]=t,i[4]=m,i[5]=a),it.apply(b,i); +if(u||a||r.length||!(Ne.fastBind||be&&e.length))f=function(){var a=arguments,i=u?this:t;return o&&(n=t[l]),(e.length||r.length)&&(he.apply(a,e),se.apply(a,r)),this instanceof f?(i=ht(n.prototype)?me(n.prototype):{},a=n.apply(i,a),ht(a)?a:i):n.apply(i,a)};else{i=[n,t],se.apply(i,e);var f=be.call.apply(be,i)}if(i=Ee.call(arguments),o){var l=t;t=n}return Be(f,i),f}function ft(n){return Fe[n]}function lt(){var n=(n=Z.indexOf)===$t?t:n;return n}function ct(n){var t,e;return n&&ye.call(n)==M&&(t=n.constructor,!yt(t)||t instanceof t)?(C(n,function(n,t){e=t +}),e===y||pe.call(n,e)):m}function pt(n){return Re[n]}function st(n){return n&&typeof n=="object"?ye.call(n)==T:m}function vt(n){var t=[];return C(n,function(n,e){yt(n)&&t.push(e)}),t.sort()}function gt(n){for(var t=-1,e=De(n),r=e.length,u={};++te?we(0,a+e):e)||0,a&&typeof a=="number"?o=-1<(mt(n)?n.indexOf(t,e):u(n,t,e)):_(n,function(n){return++ra&&(a=i)}}else t=!t&&mt(n)?u:Z.createCallback(t,e,3),Ct(n,function(n,e,u){e=t(n,e,u),e>r&&(r=e,a=n)});return a}function Et(n,t){var e=-1,r=n?n.length:0;if(typeof r=="number")for(var u=Vt(r);++earguments.length;t=Z.createCallback(t,r,4);var a=-1,o=n.length;if(typeof o=="number")for(u&&(e=n[++a]);++aarguments.length;if(typeof u!="number")var o=De(n),u=o.length;return t=Z.createCallback(t,r,4),Ct(n,function(r,i,f){i=o?o[--u]:--u,e=a?(a=m,n[i]):t(e,n[i],i,f)}),e}function It(n,t,e){var r;t=Z.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e=w&&u===t; +if(l){var c=o(i);c?(u=e,i=c):l=m}for(;++ru(i,c)&&f.push(c);return l&&s(i),f}function Bt(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=b){var a=-1;for(t=Z.createCallback(t,e,3);++ar?we(0,u+r):r||0}else if(r)return r=Ft(n,e),n[r]===e?r:-1;return n?t(n,e,r):-1}function Dt(n,t,e){if(typeof t!="number"&&t!=b){var r=0,u=-1,a=n?n.length:0; +for(t=Z.createCallback(t,e,3);++u>>1,e(n[r])e?0:e);++tl&&(i=n.apply(f,o)); +else{var e=new Ht;!s&&!y&&(c=e);var r=p-(e-c);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:Z}};var Be=ie?function(n,t){ie(n,"__bindData__",{configurable:m,enumerable:m,value:t,writable:m})}:c,$e=de,De=je?function(n){return ht(n)?je(n):[]}:X,Fe={"&":"&","<":"<",">":">",'"':""","'":"'"},Re=gt(Fe),Te=Yt("("+De(Re).join("|")+")","g"),qe=Yt("["+De(Fe).join("")+"]","g"),ze=ot(function(n,t,e){pe.call(n,e)?n[e]++:n[e]=1 +}),We=ot(function(n,t,e){(pe.call(n,e)?n[e]:n[e]=[]).push(t)}),Pe=ot(function(n,t,e){n[e]=t});Ae&&Q&&typeof ve=="function"&&(Pt=zt(ve,r));var Ke=8==xe(x+"08")?xe:function(n,t){return xe(mt(n)?n.replace(B,""):n,t||0)};return Z.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},Z.assign=L,Z.at=function(n){for(var t=-1,e=et(arguments,h,m,1),r=e.length,u=Vt(r);++t=w&&o(a?r[a]:y)}n:for(;++l(b?e(b,h):c(y,h))){for(a=u,(b||y).push(h);--a;)if(b=i[a],0>(b?e(b,h):c(r[a],h)))continue n;g.push(h)}}for(;u--;)(b=i[u])&&s(b);return p(i),p(y),g},Z.invert=gt,Z.invoke=function(n,t){var e=Ee.call(arguments,2),r=-1,u=typeof t=="function",a=n?n.length:0,o=Vt(typeof a=="number"?a:0);return Ct(n,function(n){o[++r]=(u?t:n[t]).apply(n,e)}),o},Z.keys=De,Z.map=xt,Z.max=Ot,Z.memoize=function(n,t){function e(){var r=e.cache,u=j+(t?t.apply(this,arguments):arguments[0]); +return pe.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}return e.cache={},e},Z.merge=function(n){var t=arguments,e=2;if(!ht(n))return n;if("number"!=typeof t[2]&&(e=t.length),3r(o,e))&&(a[e]=n)}),a},Z.once=function(n){var t,e;return function(){return t?e:(t=h,e=n.apply(this,arguments),n=b,e)}},Z.pairs=function(n){for(var t=-1,e=De(n),r=e.length,u=Vt(r);++te?we(0,r+e):Ce(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},Z.mixin=Mt,Z.noConflict=function(){return r._=re,this},Z.parseInt=Ke,Z.random=function(n,t){n==b&&t==b&&(t=1),n=+n||0,t==b?(t=n,n=0):t=+t||0;var e=Oe();return n%1||t%1?n+Ce(e*(t-n+parseFloat("1e-"+((e+"").length-1))),t):n+fe(e*(t-n+1))},Z.reduce=St,Z.reduceRight=At,Z.result=function(n,t){var e=n?n[t]:y; +return yt(e)?n[t]():e},Z.runInContext=g,Z.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:De(n).length},Z.some=It,Z.sortedIndex=Ft,Z.template=function(n,t,e){var r=Z.templateSettings;n||(n=""),e=J({},e,r);var u,a=J({},e.imports,r.imports),r=De(a),a=dt(a),o=0,f=e.interpolate||$,l="__p+='",f=Yt((e.escape||$).source+"|"+f.source+"|"+(f===N?A:$).source+"|"+(e.evaluate||$).source+"|$","g");n.replace(f,function(t,e,r,a,f,c){return r||(r=a),l+=n.slice(o,c).replace(F,i),e&&(l+="'+__e("+e+")+'"),f&&(u=h,l+="';"+f+";__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),o=c+t.length,t +}),l+="';\n",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(O,""):l).replace(E,"$1").replace(S,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=Jt(r,"return "+l).apply(y,a)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},Z.unescape=function(n){return n==b?"":Zt(n).replace(Te,pt)},Z.uniqueId=function(n){var t=++k;return Zt(n==b?"":n)+t +},Z.all=kt,Z.any=It,Z.detect=wt,Z.findWhere=wt,Z.foldl=St,Z.foldr=At,Z.include=_t,Z.inject=St,_(Z,function(n,t){Z.prototype[t]||(Z.prototype[t]=function(){var t=[this.__wrapped__];return se.apply(t,arguments),n.apply(Z,t)})}),Z.first=Bt,Z.last=function(n,t,e){if(n){var r=0,u=n.length;if(typeof t!="number"&&t!=b){var a=u;for(t=Z.createCallback(t,e,3);a--&&t(n[a],a,n);)r++}else if(r=t,r==b||e)return n[u-1];return v(n,we(0,u-r))}},Z.take=Bt,Z.head=Bt,_(Z,function(n,t){Z.prototype[t]||(Z.prototype[t]=function(t,e){var r=n(this.__wrapped__,t,e); +return t==b||e&&typeof t!="function"?r:new nt(r)})}),Z.VERSION="1.3.1",Z.prototype.toString=function(){return Zt(this.__wrapped__)},Z.prototype.value=Ut,Z.prototype.valueOf=Ut,Ct(["join","pop","shift"],function(n){var t=te[n];Z.prototype[n]=function(){return t.apply(this.__wrapped__,arguments)}}),Ct(["push","reverse","sort","unshift"],function(n){var t=te[n];Z.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),Ct(["concat","slice","splice"],function(n){var t=te[n];Z.prototype[n]=function(){return new nt(t.apply(this.__wrapped__,arguments)) +}}),Z}var y,h=!0,b=null,m=!1,d=[],_=[],k=0,j=+new Date+"",w=75,C=40,x=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",O=/\b__p\+='';/g,E=/\b(__p\+=)''\+/g,S=/(__e\(.*?\)|\b__t\))\+'';/g,A=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,I=/\w*$/,N=/<%=([\s\S]+?)%>/g,B=RegExp("^["+x+"]*0+(?=.$)"),$=/($^)/,D=(D=/\bthis\b/)&&D.test(g)&&D,F=/['\n\r\t\u2028\u2029\\]/g,R="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setImmediate setTimeout".split(" "),T="[object Arguments]",q="[object Array]",z="[object Boolean]",W="[object Date]",P="[object Function]",K="[object Number]",M="[object Object]",U="[object RegExp]",V="[object String]",G={}; +G[P]=m,G[T]=G[q]=G[z]=G[W]=G[K]=G[M]=G[U]=G[V]=h;var H={"boolean":m,"function":h,object:h,number:m,string:m,undefined:m},J={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},L=H[typeof exports]&&exports,Q=H[typeof module]&&module&&module.exports==L&&module,X=H[typeof global]&&global;!X||X.global!==X&&X.window!==X||(n=X);var Y=g();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=Y, define(function(){return Y})):L&&!L.nodeType?Q?(Q.exports=Y)._=Y:L._=Y:n._=Y }(this); \ No newline at end of file diff --git a/dist/lodash.underscore.js b/dist/lodash.underscore.js index 8e07f85d6..d43ad7511 100644 --- a/dist/lodash.underscore.js +++ b/dist/lodash.underscore.js @@ -212,12 +212,12 @@ * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`, * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`, - * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`, - * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, - * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, - * `unzip`, `values`, `where`, `without`, `wrap`, and `zip` + * `forOwn`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, + * `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, + * `omit`, `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, + * `range`, `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, and `zip` * * The non-chainable wrapper functions are: * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, @@ -531,6 +531,28 @@ return result; } + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg, 3); + forEach(collection, function(value, key, collection) { + key = String(callback(value, key, collection)); + setter(result, value, key, collection); + }); + return result; + }; + } + /** * Creates a function that, when called, invokes `func` with the `this` binding * of `thisArg` and prepends any `partialArgs` to the arguments passed to the @@ -1251,7 +1273,7 @@ * Checks if `value` is `NaN`. * * Note: This is not the same as native `isNaN`, which will return `true` for - * `undefined` and other values. See http://es5.github.io/#x15.1.2.4. + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. * * @static * @memberOf _ @@ -1544,10 +1566,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the given `callback`. The corresponding value of each key - * is the number of times the key was returned by the `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the number of times the key was returned by the `callback`. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -1576,16 +1599,9 @@ * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg, 3); - - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); /** * Checks if the `callback` returns a truthy value for **all** elements of a @@ -1847,10 +1863,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the `callback`. The corresponding value of each key is - * an array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the `callback`. The corresponding + * value of each key is an array of the elements responsible for generating + * the key. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -1880,16 +1897,9 @@ * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = createCallback(callback, thisArg, 3); - - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); /** * Invokes the method named by `methodName` on each element in the `collection`, @@ -2961,7 +2971,8 @@ /** * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. * * @static * @memberOf _ @@ -3495,6 +3506,7 @@ return result; }; } + // exit early if there is no `thisArg` if (typeof thisArg == 'undefined') { return func; } @@ -3512,9 +3524,7 @@ return func.call(thisArg, accumulator, value, index, collection); }; } - return function() { - return func.apply(thisArg, arguments); - }; + return bind(func, thisArg); } /** diff --git a/dist/lodash.underscore.min.js b/dist/lodash.underscore.min.js index cd3b5c4d1..a61f0d7e2 100644 --- a/dist/lodash.underscore.min.js +++ b/dist/lodash.underscore.min.js @@ -3,33 +3,33 @@ * Lo-Dash 1.3.1 (Custom Build) lodash.com/license | Underscore.js 1.5.1 underscorejs.org/LICENSE * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js` */ -;!function(n){function t(n,t){var r;if(n&&ht[typeof n])for(r in n)if(Ot.call(n,r)&&t(n[r],r,n)===et)break}function r(n,t){var r;if(n&&ht[typeof n])for(r in n)if(t(n[r],r,n)===et)break}function e(n){var t,r=[];if(!n||!ht[typeof n])return r;for(t in n)Ot.call(n,t)&&r.push(t);return r}function u(n,t,r){r=(r||0)-1;for(var e=n?n.length:0;++rt||typeof n=="undefined")return 1;if(nu(a,c))&&(r&&a.push(c),o.push(f))}return o}function v(n,t,r,e){var u=[];if(!A(n))throw new TypeError;if(e||u.length||!(zt.fastBind||Ft&&r.length))o=function(){var i=arguments,a=e?this:t;return(r.length||u.length)&&(St.apply(i,r),Et.apply(i,u)),this instanceof o?(a=g(n.prototype),i=n.apply(a,i),O(i)?i:a):n.apply(a,i) -};else{var i=[n,t];Et.apply(i,r);var o=Ft.call.apply(Ft,i)}return o}function g(n){return O(n)?Nt(n):{}}function h(n){return Ut[n]}function y(){var n=(n=f.indexOf)===U?u:n;return n}function m(n){return Vt[n]}function _(n){return n&&typeof n=="object"?Tt.call(n)==at:tt}function d(n){if(!n)return n;for(var t=1,r=arguments.length;te&&(e=r,u=n)});else for(;++iu&&(u=r);return u}function M(n,t){var r=-1,e=n?n.length:0;if(typeof e=="number")for(var u=Array(e);++rarguments.length;r=K(r,u,4);var o=-1,a=n.length;if(typeof a=="number")for(i&&(e=n[++o]);++oarguments.length; -if(typeof u!="number")var o=Pt(n),u=o.length;return t=K(t,e,4),B(n,function(e,a,f){a=o?o[--u]:--u,r=i?(i=tt,n[a]):t(r,n[a],a,f)}),r}function W(n,r,e){var u;r=K(r,e,3),e=-1;var i=n?n.length:0;if(typeof i=="number")for(;++er(u,o)&&i.push(o)}return i}function P(n,t,r){if(n){var e=0,u=n.length; -if(typeof t!="number"&&t!=nt){var i=-1;for(t=K(t,r,3);++ir?qt(0,e+r):r||0}else if(r)return r=G(n,t),n[r]===t?r:-1;return n?u(n,t,r):-1}function V(n,t,r){if(typeof t!="number"&&t!=nt){var e=0,u=-1,i=n?n.length:0;for(t=K(t,r,3);++u>>1,r(n[e])c&&(a=n.apply(f,o));else{var r=new Date;!s&&!h&&(l=r);var e=p-(r-l);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},Nt||(g=function(n){if(O(n)){a.prototype=n;var t=new a;a.prototype=nt}return t||{}}),_(arguments)||(_=function(n){return n&&typeof n=="object"?Ot.call(n,"callee"):tt});var Ct=Rt||function(n){return n&&typeof n=="object"?Tt.call(n)==ft:tt},Pt=Dt?function(n){return O(n)?Dt(n):[] -}:e,Ut={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},Vt=w(Ut),Gt=RegExp("("+Pt(Vt).join("|")+")","g"),Ht=RegExp("["+Pt(Ut).join("")+"]","g");A(/x/)&&(A=function(n){return typeof n=="function"&&"[object Function]"==Tt.call(n)}),f.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},f.bind=J,f.bindAll=function(n){for(var t=1u(o,a)){for(var f=r;--f;)if(0>u(t[f],a))continue n; -o.push(a)}}return o},f.invert=w,f.invoke=function(n,t){var r=It.call(arguments,2),e=-1,u=typeof t=="function",i=n?n.length:0,o=Array(typeof i=="number"?i:0);return B(n,function(n){o[++e]=(u?t:n[t]).apply(n,r)}),o},f.keys=Pt,f.map=D,f.max=q,f.memoize=function(n,t){var r={};return function(){var e=ut+(t?t.apply(this,arguments):arguments[0]);return Ot.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},f.min=function(n,t,r){var e=1/0,u=e,i=-1,o=n?n.length:0;if(t||typeof o!="number")t=K(t,r,3),B(n,function(n,r,i){r=t(n,r,i),rt(e,r)&&(u[r]=n)}),u},f.once=function(n){var t,r;return function(){return t?r:(t=Z,r=n.apply(this,arguments),n=nt,r)}},f.pairs=function(n){for(var t=-1,r=Pt(n),e=r.length,u=Array(e);++tt?0:t);++nr?qt(0,e+r):Mt(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},f.mixin=X,f.noConflict=function(){return n._=jt,this},f.random=function(n,t){n==nt&&t==nt&&(t=1),n=+n||0,t==nt?(t=n,n=0):t=+t||0;var r=$t();return n%1||t%1?n+Mt(r*(t-n+parseFloat("1e-"+((r+"").length-1))),t):n+At(r*(t-n+1)) -},f.reduce=$,f.reduceRight=I,f.result=function(n,t){var r=n?n[t]:Y;return A(r)?n[t]():r},f.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Pt(n).length},f.some=W,f.sortedIndex=G,f.template=function(n,t,r){var e=f.templateSettings;n||(n=""),r=b({},r,e);var u=0,i="__p+='",e=r.variable;n.replace(RegExp((r.escape||it).source+"|"+(r.interpolate||it).source+"|"+(r.evaluate||it).source+"|$","g"),function(t,r,e,a,f){return i+=n.slice(u,f).replace(ot,o),r&&(i+="'+_.escape("+r+")+'"),a&&(i+="';"+a+";__p+='"),e&&(i+="'+((__t=("+e+"))==null?'':__t)+'"),u=f+t.length,t -}),i+="';\n",e||(e="obj",i="with("+e+"||{}){"+i+"}"),i="function("+e+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+i+"return __p}";try{var a=Function("_","return "+i)(f)}catch(c){throw c.source=i,c}return t?a(t):(a.source=i,a)},f.unescape=function(n){return n==nt?"":(n+"").replace(Gt,m)},f.uniqueId=function(n){var t=++rt+"";return n?n+t:t},f.all=N,f.any=W,f.detect=k,f.findWhere=function(n,t){return z(n,t,Z)},f.foldl=$,f.foldr=I,f.include=F,f.inject=$,f.first=P,f.last=function(n,t,r){if(n){var e=0,u=n.length; -if(typeof t!="number"&&t!=nt){var i=u;for(t=K(t,r,3);i--&&t(n[i],i,n);)e++}else if(e=t,e==nt||r)return n[u-1];return It.call(n,qt(0,u-e))}},f.take=P,f.head=P,f.VERSION="1.3.1",X(f),f.prototype.chain=function(){return this.__chain__=Z,this},f.prototype.value=function(){return this.__wrapped__},B("pop push reverse shift sort splice unshift".split(" "),function(n){var t=bt[n];f.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),!zt.spliceObjects&&0===n.length&&delete n[0],this -}}),B(["concat","join","slice"],function(n){var t=bt[n];f.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new c(n),n.__chain__=Z),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=f, define(function(){return f})):mt&&!mt.nodeType?_t?(_t.exports=f)._=f:mt._=f:n._=f}(this); \ No newline at end of file +;!function(n){function t(n,t){var r;if(n&&yt[typeof n])for(r in n)if(Tt.call(n,r)&&t(n[r],r,n)===ut)break}function r(n,t){var r;if(n&&yt[typeof n])for(r in n)if(t(n[r],r,n)===ut)break}function e(n){var t,r=[];if(!n||!yt[typeof n])return r;for(t in n)Tt.call(n,t)&&r.push(t);return r}function u(n,t,r){r=(r||0)-1;for(var e=n?n.length:0;++rt||typeof n=="undefined")return 1;if(nu(a,c))&&(r&&a.push(c),o.push(f))}return o}function v(n){return function(t,r,e){var u={};return r=L(r,e,3),D(t,function(t,e,i){e=r(t,e,i)+"",n(u,t,e,i)}),u}}function g(n,t,r,e){var u=[];if(!O(n))throw new TypeError;if(e||u.length||!(Ut.fastBind||Rt&&r.length))o=function(){var i=arguments,a=e?this:t;return(r.length||u.length)&&(Nt.apply(i,r),St.apply(i,u)),this instanceof o?(a=h(n.prototype),i=n.apply(a,i),E(i)?i:a):n.apply(a,i) +};else{var i=[n,t];St.apply(i,r);var o=Rt.call.apply(Rt,i)}return o}function h(n){return E(n)?kt(n):{}}function y(n){return Ht[n]}function m(){var n=(n=f.indexOf)===V?u:n;return n}function _(n){return Jt[n]}function d(n){return n&&typeof n=="object"?Ft.call(n)==ft:rt}function b(n){if(!n)return n;for(var t=1,r=arguments.length;te&&(e=r,u=n)});else for(;++iu&&(u=r);return u}function $(n,t){var r=-1,e=n?n.length:0;if(typeof e=="number")for(var u=Array(e);++rarguments.length;r=L(r,u,4);var o=-1,a=n.length;if(typeof a=="number")for(i&&(e=n[++o]);++oarguments.length; +if(typeof u!="number")var o=Gt(n),u=o.length;return t=L(t,e,4),D(n,function(e,a,f){a=o?o[--u]:--u,r=i?(i=rt,n[a]):t(r,n[a],a,f)}),r}function z(n,r,e){var u;r=L(r,e,3),e=-1;var i=n?n.length:0;if(typeof i=="number")for(;++er(u,o)&&i.push(o)}return i}function U(n,t,r){if(n){var e=0,u=n.length; +if(typeof t!="number"&&t!=tt){var i=-1;for(t=L(t,r,3);++ir?$t(0,e+r):r||0}else if(r)return r=H(n,t),n[r]===t?r:-1;return n?u(n,t,r):-1}function G(n,t,r){if(typeof t!="number"&&t!=tt){var e=0,u=-1,i=n?n.length:0;for(t=L(t,r,3);++u>>1,r(n[e])c&&(a=n.apply(f,o));else{var r=new Date;!s&&!h&&(l=r);var e=p-(r-l);0/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},kt||(h=function(n){if(E(n)){a.prototype=n;var t=new a;a.prototype=tt}return t||{}}),d(arguments)||(d=function(n){return n&&typeof n=="object"?Tt.call(n,"callee"):rt});var Vt=Bt||function(n){return n&&typeof n=="object"?Ft.call(n)==ct:rt},Gt=Mt?function(n){return E(n)?Mt(n):[] +}:e,Ht={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},Jt=x(Ht),Kt=RegExp("("+Gt(Jt).join("|")+")","g"),Lt=RegExp("["+Gt(Ht).join("")+"]","g");O(/x/)&&(O=function(n){return typeof n=="function"&&"[object Function]"==Ft.call(n)});var Qt=v(function(n,t,r){Tt.call(n,r)?n[r]++:n[r]=1}),Xt=v(function(n,t,r){(Tt.call(n,r)?n[r]:n[r]=[]).push(t)});f.after=function(n,t){return function(){return 1>--n?t.apply(this,arguments):void 0}},f.bind=K,f.bindAll=function(n){for(var t=1u(o,a)){for(var f=r;--f;)if(0>u(t[f],a))continue n;o.push(a)}}return o},f.invert=x,f.invoke=function(n,t){var r=zt.call(arguments,2),e=-1,u=typeof t=="function",i=n?n.length:0,o=Array(typeof i=="number"?i:0); +return D(n,function(n){o[++e]=(u?t:n[t]).apply(n,r)}),o},f.keys=Gt,f.map=q,f.max=M,f.memoize=function(n,t){var r={};return function(){var e=it+(t?t.apply(this,arguments):arguments[0]);return Tt.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},f.min=function(n,t,r){var e=1/0,u=e,i=-1,o=n?n.length:0;if(t||typeof o!="number")t=L(t,r,3),D(n,function(n,r,i){r=t(n,r,i),rt(e,r)&&(u[r]=n) +}),u},f.once=function(n){var t,r;return function(){return t?r:(t=nt,r=n.apply(this,arguments),n=tt,r)}},f.pairs=function(n){for(var t=-1,r=Gt(n),e=r.length,u=Array(e);++tt?0:t);++nr?$t(0,e+r):It(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},f.mixin=Y,f.noConflict=function(){return n._=xt,this},f.random=function(n,t){n==tt&&t==tt&&(t=1),n=+n||0,t==tt?(t=n,n=0):t=+t||0;var r=Wt();return n%1||t%1?n+It(r*(t-n+parseFloat("1e-"+((r+"").length-1))),t):n+Et(r*(t-n+1))},f.reduce=I,f.reduceRight=W,f.result=function(n,t){var r=n?n[t]:Z; +return O(r)?n[t]():r},f.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Gt(n).length},f.some=z,f.sortedIndex=H,f.template=function(n,t,r){var e=f.templateSettings;n||(n=""),r=j({},r,e);var u=0,i="__p+='",e=r.variable;n.replace(RegExp((r.escape||ot).source+"|"+(r.interpolate||ot).source+"|"+(r.evaluate||ot).source+"|$","g"),function(t,r,e,a,f){return i+=n.slice(u,f).replace(at,o),r&&(i+="'+_.escape("+r+")+'"),a&&(i+="';"+a+";__p+='"),e&&(i+="'+((__t=("+e+"))==null?'':__t)+'"),u=f+t.length,t +}),i+="';\n",e||(e="obj",i="with("+e+"||{}){"+i+"}"),i="function("+e+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+i+"return __p}";try{var a=Function("_","return "+i)(f)}catch(c){throw c.source=i,c}return t?a(t):(a.source=i,a)},f.unescape=function(n){return n==tt?"":(n+"").replace(Kt,_)},f.uniqueId=function(n){var t=++et+"";return n?n+t:t},f.all=R,f.any=z,f.detect=B,f.findWhere=function(n,t){return C(n,t,nt)},f.foldl=I,f.foldr=W,f.include=N,f.inject=I,f.first=U,f.last=function(n,t,r){if(n){var e=0,u=n.length; +if(typeof t!="number"&&t!=tt){var i=u;for(t=L(t,r,3);i--&&t(n[i],i,n);)e++}else if(e=t,e==tt||r)return n[u-1];return zt.call(n,$t(0,u-e))}},f.take=U,f.head=U,f.VERSION="1.3.1",Y(f),f.prototype.chain=function(){return this.__chain__=nt,this},f.prototype.value=function(){return this.__wrapped__},D("pop push reverse shift sort splice unshift".split(" "),function(n){var t=jt[n];f.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),!Ut.spliceObjects&&0===n.length&&delete n[0],this +}}),D(["concat","join","slice"],function(n){var t=jt[n];f.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new c(n),n.__chain__=nt),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(n._=f, define(function(){return f})):_t&&!_t.nodeType?dt?(dt.exports=f)._=f:_t._=f:n._=f}(this); \ No newline at end of file diff --git a/lodash.js b/lodash.js index b6005c344..2e1c44ade 100644 --- a/lodash.js +++ b/lodash.js @@ -561,12 +561,12 @@ * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`, * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`, - * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`, - * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, - * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`, - * `unzip`, `values`, `where`, `without`, `wrap`, and `zip` + * `forOwn`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, + * `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, + * `omit`, `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, + * `range`, `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, + * `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, and `zip` * * The non-chainable wrapper functions are: * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, @@ -1343,6 +1343,28 @@ return result; } + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + forEach(collection, function(value, key, collection) { + key = String(callback(value, key, collection)); + setter(result, value, key, collection); + }); + return result; + }; + } + /** * Creates a function that, when called, invokes `func` with the `this` binding * of `thisArg` and prepends any `partialArgs` to the arguments passed to the @@ -1527,14 +1549,14 @@ * @param {Function} func The function to set data on. * @param {Mixed} value The value to set. */ - function setBindData(func, value) { + var setBindData = !defineProperty ? noop : function(func, value) { defineProperty(func, '__bindData__', { 'configurable': false, 'enumerable': false, 'value': value, 'writable': false }); - } + }; /** * A fallback implementation of `isPlainObject` which checks if a given `value` @@ -2285,7 +2307,7 @@ * Checks if `value` is `NaN`. * * Note: This is not the same as native `isNaN`, which will return `true` for - * `undefined` and other values. See http://es5.github.io/#x15.1.2.4. + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. * * @static * @memberOf _ @@ -2807,10 +2829,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the given `callback`. The corresponding value of each key - * is the number of times the key was returned by the `callback`. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the number of times the key was returned by the `callback`. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -2839,16 +2862,9 @@ * _.countBy(['one', 'two', 'three'], 'length'); * // => { '3': 2, '5': 1 } */ - function countBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); - return result; - } + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); /** * Checks if the `callback` returns a truthy value for **all** elements of a @@ -3083,10 +3099,11 @@ } /** - * Creates an object composed of keys returned from running each element of the - * `collection` through the `callback`. The corresponding value of each key is - * an array of elements passed to `callback` that returned the key. The `callback` - * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the `callback`. The corresponding + * value of each key is an array of the elements responsible for generating + * the key. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). * * If a property name is passed for `callback`, the created "_.pluck" style * callback will return the property value of the given element. @@ -3116,16 +3133,52 @@ * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ - function groupBy(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); - forEach(collection, function(value, key, collection) { - key = String(callback(value, key, collection)); - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); - return result; - } + /** + * Creates an object composed of keys generated from the results of running + * each element of the `collection` through the given `callback`. The corresponding + * value of each key is the last element responsible for generating the key. + * The `callback` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** * Invokes the method named by `methodName` on each element in the `collection`, @@ -4263,7 +4316,8 @@ /** * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. * * @static * @memberOf _ @@ -5786,6 +5840,7 @@ lodash.forOwn = forOwn; lodash.functions = functions; lodash.groupBy = groupBy; + lodash.indexBy = indexBy; lodash.initial = initial; lodash.intersection = intersection; lodash.invert = invert; diff --git a/test/test-build.js b/test/test-build.js index 1cd5ed935..ed0dedb0e 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -128,6 +128,7 @@ 'findWhere', 'forEach', 'groupBy', + 'indexBy', 'invoke', 'map', 'max', @@ -280,6 +281,7 @@ 'findKey', 'forIn', 'forOwn', + 'indexBy', 'isPlainObject', 'merge', 'parseInt',