mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 23:37:49 +00:00
Add array and object pools to lodash.
Former-commit-id: f038284d6a544e146dc271ed0fbea0d7401593d4
This commit is contained in:
122
build.js
122
build.js
@@ -85,7 +85,7 @@
|
||||
'bind': ['createBound'],
|
||||
'bindAll': ['bind', 'functions'],
|
||||
'bindKey': ['createBound'],
|
||||
'clone': ['assign', 'forEach', 'forOwn', 'isArray', 'isObject', 'isNode', 'slice'],
|
||||
'clone': ['assign', 'forEach', 'forOwn', 'getArray', 'isArray', 'isObject', 'isNode', 'releaseArray', 'slice'],
|
||||
'cloneDeep': ['clone'],
|
||||
'compact': [],
|
||||
'compose': [],
|
||||
@@ -114,7 +114,7 @@
|
||||
'identity': [],
|
||||
'indexOf': ['basicIndexOf', 'sortedIndex'],
|
||||
'initial': ['slice'],
|
||||
'intersection': ['createCache'],
|
||||
'intersection': ['createCache', 'getArray', 'releaseArray'],
|
||||
'invert': ['keys'],
|
||||
'invoke': ['forEach'],
|
||||
'isArguments': [],
|
||||
@@ -123,7 +123,7 @@
|
||||
'isDate': [],
|
||||
'isElement': [],
|
||||
'isEmpty': ['forOwn', 'isArguments', 'isFunction'],
|
||||
'isEqual': ['forIn', 'isArguments', 'isFunction', 'isNode'],
|
||||
'isEqual': ['forIn', 'getArray', 'isArguments', 'isFunction', 'isNode', 'releaseArray'],
|
||||
'isFinite': [],
|
||||
'isFunction': [],
|
||||
'isNaN': ['isNumber'],
|
||||
@@ -140,7 +140,7 @@
|
||||
'map': ['basicEach', 'createCallback', 'isArray'],
|
||||
'max': ['basicEach', 'charAtCallback', 'createCallback', 'isArray', 'isString'],
|
||||
'memoize': [],
|
||||
'merge': ['forEach', 'forOwn', 'isArray', 'isObject', 'isPlainObject'],
|
||||
'merge': ['forEach', 'forOwn', 'getArray', 'isArray', 'isObject', 'isPlainObject', 'releaseArray'],
|
||||
'min': ['basicEach', 'charAtCallback', 'createCallback', 'isArray', 'isString'],
|
||||
'mixin': ['forEach', 'functions'],
|
||||
'noConflict': [],
|
||||
@@ -163,7 +163,7 @@
|
||||
'shuffle': ['forEach'],
|
||||
'size': ['keys'],
|
||||
'some': ['basicEach', 'createCallback', 'isArray'],
|
||||
'sortBy': ['compareAscending', 'createCallback', 'forEach'],
|
||||
'sortBy': ['compareAscending', 'createCallback', 'forEach', 'getObject', 'releaseObject'],
|
||||
'sortedIndex': ['createCallback', 'identity'],
|
||||
'tap': ['value'],
|
||||
'template': ['defaults', 'escape', 'escapeStringChar', 'keys', 'values'],
|
||||
@@ -173,7 +173,7 @@
|
||||
'transform': ['createCallback', 'createObject', 'forOwn', 'isArray'],
|
||||
'unescape': ['unescapeHtmlChar'],
|
||||
'union': ['isArray', 'uniq'],
|
||||
'uniq': ['createCache', 'getIndexOf', 'overloadWrapper'],
|
||||
'uniq': ['createCache', 'getArray', 'getIndexOf', 'overloadWrapper', 'releaseArray'],
|
||||
'uniqueId': [],
|
||||
'unzip': ['max', 'pluck'],
|
||||
'value': ['basicEach', 'forOwn', 'isArray', 'lodashWrapper'],
|
||||
@@ -190,17 +190,21 @@
|
||||
'charAtCallback': [],
|
||||
'compareAscending': [],
|
||||
'createBound': ['createObject', 'isFunction', 'isObject'],
|
||||
'createCache': ['basicIndexOf', 'getIndexOf'],
|
||||
'createIterator': ['iteratorTemplate'],
|
||||
'createCache': ['basicIndexOf', 'getArray', 'getIndexOf', 'getObject', 'releaseObject'],
|
||||
'createIterator': ['getObject', 'iteratorTemplate', 'releaseObject'],
|
||||
'createObject': [ 'isObject', 'noop'],
|
||||
'escapeHtmlChar': [],
|
||||
'escapeStringChar': [],
|
||||
'getArray': [],
|
||||
'getIndexOf': ['basicIndexOf', 'indexOf'],
|
||||
'getObject': [],
|
||||
'iteratorTemplate': [],
|
||||
'isNode': [],
|
||||
'lodashWrapper': [],
|
||||
'noop': [],
|
||||
'overloadWrapper': ['createCallback'],
|
||||
'releaseArray': [],
|
||||
'releaseObject': [],
|
||||
'shimIsPlainObject': ['forIn', 'isArguments', 'isFunction', 'isNode'],
|
||||
'shimKeys': ['createIterator', 'isArguments'],
|
||||
'slice': [],
|
||||
@@ -222,9 +226,7 @@
|
||||
'shadowedProps',
|
||||
'top',
|
||||
'useHas',
|
||||
'useKeys',
|
||||
'shimIsPlainObject',
|
||||
'shimKyes'
|
||||
'useKeys'
|
||||
];
|
||||
|
||||
/** List of all methods */
|
||||
@@ -309,9 +311,6 @@
|
||||
'unzip'
|
||||
];
|
||||
|
||||
/** List of Underscore methods */
|
||||
var underscoreMethods = _.without.apply(_, [allMethods].concat(lodashOnlyMethods));
|
||||
|
||||
/** List of ways to export the `lodash` function */
|
||||
var exportsAll = [
|
||||
'amd',
|
||||
@@ -341,15 +340,22 @@
|
||||
'createIterator',
|
||||
'escapeHtmlChar',
|
||||
'escapeStringChar',
|
||||
'getArray',
|
||||
'getObject',
|
||||
'isNode',
|
||||
'iteratorTemplate',
|
||||
'lodashWrapper',
|
||||
'overloadWrapper',
|
||||
'releaseArray',
|
||||
'releaseObject',
|
||||
'shimIsPlainObject',
|
||||
'shimKeys',
|
||||
'slice',
|
||||
'unescapeHtmlChar'
|
||||
]
|
||||
];
|
||||
|
||||
/** List of Underscore methods */
|
||||
var underscoreMethods = _.without.apply(_, [allMethods].concat(lodashOnlyMethods, privateMethods));
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
@@ -990,7 +996,7 @@
|
||||
// match a function declaration
|
||||
'function ' + funcName + '\\b[\\s\\S]+?\\n\\1}|' +
|
||||
// match a variable declaration with function expression
|
||||
'var ' + funcName + ' *=.*?function[\\s\\S]+?\\n\\1};' +
|
||||
'var ' + funcName + ' *=.*?function[\\s\\S]+?\\n\\1}(?:\\(\\)\\))?;' +
|
||||
// end non-capturing group
|
||||
')\\n'
|
||||
)));
|
||||
@@ -1051,24 +1057,30 @@
|
||||
return source;
|
||||
}
|
||||
// remove data object property assignment
|
||||
var modified = snippet
|
||||
.replace(RegExp("^(?: *\\/\\/.*\\n)* *'" + identifier + "':.+\\n+", 'm'), '')
|
||||
.replace(/,(?=\s*})/, '');
|
||||
var modified = snippet.replace(RegExp("^(?: *\\/\\/.*\\n)* *data\\." + identifier + " *= *(.+\\n+)", 'm'), function(match, postlude) {
|
||||
return /\bdata\b/.test(postlude) ? postlude : '';
|
||||
});
|
||||
|
||||
source = source.replace(snippet, function() {
|
||||
return modified;
|
||||
});
|
||||
|
||||
// clip at the `factory` assignment
|
||||
// clip to the `factory` assignment
|
||||
snippet = modified.match(/Function\([\s\S]+$/)[0];
|
||||
|
||||
modified = snippet
|
||||
.replace(RegExp('\\b' + identifier + '\\b,? *', 'g'), '')
|
||||
.replace(/, *(?=',)/, '')
|
||||
.replace(/,(?=\s*\))/, '')
|
||||
// remove `factory` arguments
|
||||
source = source.replace(snippet, function(match) {
|
||||
return match
|
||||
.replace(RegExp('\\b' + identifier + '\\b,? *', 'g'), '')
|
||||
.replace(/, *(?=',)/, '')
|
||||
.replace(/,(?=\s*\))/, '');
|
||||
});
|
||||
|
||||
source = source.replace(snippet, function() {
|
||||
return modified;
|
||||
// remove property assignment from `getObject`
|
||||
source = source.replace(matchFunction(source, 'getObject'), function(match) {
|
||||
return match
|
||||
.replace(RegExp("^(?: *\\/\\/.*\\n)* *'" + identifier + "':.+\\n+", 'm'), '')
|
||||
.replace(/,(?=\s*})/, '');
|
||||
});
|
||||
|
||||
return source;
|
||||
@@ -1952,6 +1964,15 @@
|
||||
dependencyMap.where.push('find', 'isEmpty');
|
||||
}
|
||||
|
||||
_.each(['clone', 'difference', 'intersection', 'isEqual', 'sortBy', 'uniq'], function(methodName) {
|
||||
if (methodName == 'clone'
|
||||
? (!useLodashMethod('clone') && !useLodashMethod('cloneDeep'))
|
||||
: !useLodashMethod(methodName)
|
||||
) {
|
||||
dependencyMap[methodName] = _.without(dependencyMap[methodName], 'getArray', 'getObject', 'releaseArray', 'releaseObject');
|
||||
}
|
||||
});
|
||||
|
||||
_.each(['debounce', 'throttle'], function(methodName) {
|
||||
if (!useLodashMethod(methodName)) {
|
||||
dependencyMap[methodName] = [];
|
||||
@@ -1964,6 +1985,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
_.each(['flatten', 'uniq'], function(methodName) {
|
||||
if (!useLodashMethod(methodName)) {
|
||||
dependencyMap[methodName] = _.without(dependencyMap[methodName], 'overloadWrapper');
|
||||
}
|
||||
});
|
||||
|
||||
_.each(['max', 'min'], function(methodName) {
|
||||
if (!useLodashMethod(methodName)) {
|
||||
dependencyMap[methodName] = _.without(dependencyMap[methodName], 'charAtCallback', 'isArray', 'isString');
|
||||
@@ -1973,6 +2000,12 @@
|
||||
if (isModern || isUnderscore) {
|
||||
dependencyMap.reduceRight = _.without(dependencyMap.reduceRight, 'isString');
|
||||
|
||||
_.each(['assign', 'basicEach', 'defaults', 'forIn', 'forOwn', 'shimKeys'], function(methodName) {
|
||||
if (!(isUnderscore && useLodashMethod(methodName))) {
|
||||
dependencyMap[methodName] = _.without(dependencyMap[methodName], 'createIterator');
|
||||
}
|
||||
});
|
||||
|
||||
_.each(['at', 'forEach', 'toArray'], function(methodName) {
|
||||
if (!(isUnderscore && useLodashMethod(methodName))) {
|
||||
dependencyMap[methodName] = _.without(dependencyMap[methodName], 'isString');
|
||||
@@ -2644,6 +2677,32 @@
|
||||
'}'
|
||||
].join('\n'));
|
||||
}
|
||||
// replace `_.sortBy`
|
||||
if (!useLodashMethod('sortBy')) {
|
||||
source = replaceFunction(source, 'sortBy', [
|
||||
'function sortBy(collection, callback, thisArg) {',
|
||||
' var index = -1,',
|
||||
' length = collection ? collection.length : 0,',
|
||||
" result = Array(typeof length == 'number' ? length : 0);",
|
||||
'',
|
||||
' callback = lodash.createCallback(callback, thisArg);',
|
||||
' forEach(collection, function(value, key, collection) {',
|
||||
' result[++index] = {',
|
||||
" 'criteria': callback(value, key, collection),",
|
||||
" 'index': index,",
|
||||
" 'value': value",
|
||||
' };',
|
||||
' });',
|
||||
'',
|
||||
' length = result.length;',
|
||||
' result.sort(compareAscending);',
|
||||
' while (length--) {',
|
||||
' result[length] = result[length].value;',
|
||||
' }',
|
||||
' return result;',
|
||||
'}'
|
||||
].join('\n'));
|
||||
}
|
||||
// replace `_.template`
|
||||
if (!useLodashMethod('template')) {
|
||||
// remove `_.templateSettings.imports assignment
|
||||
@@ -2846,7 +2905,10 @@
|
||||
|
||||
// replace `slice` with `nativeSlice.call`
|
||||
_.each(['clone', 'first', 'initial', 'last', 'rest', 'toArray'], function(methodName) {
|
||||
if (!useLodashMethod(methodName)) {
|
||||
if (methodName == 'clone'
|
||||
? (!useLodashMethod('clone') && !useLodashMethod('cloneDeep'))
|
||||
: !useLodashMethod(methodName)
|
||||
) {
|
||||
source = source.replace(matchFunction(source, methodName), function(match) {
|
||||
return match.replace(/([^.])\bslice\(/g, '$1nativeSlice.call(');
|
||||
});
|
||||
@@ -3163,6 +3225,12 @@
|
||||
source = removeVar(source, 'htmlEscapes');
|
||||
source = removeVar(source, 'htmlUnescapes');
|
||||
}
|
||||
if (isRemoved(source, 'getArray', 'releaseArray')) {
|
||||
source = removeVar(source, 'arrayPool');
|
||||
}
|
||||
if (isRemoved(source, 'getObject', 'releaseObject')) {
|
||||
source = removeVar(source, 'objectPool');
|
||||
}
|
||||
if (isRemoved(source, 'invert')) {
|
||||
source = replaceVar(source, 'htmlUnescapes', "{'&':'&','<':'<','>':'>','"':'\"',''':\"'\"}");
|
||||
}
|
||||
|
||||
@@ -312,11 +312,32 @@
|
||||
// remove debug sourceURL use in `_.template`
|
||||
source = source.replace(/(?:\s*\/\/.*\n)* *var sourceURL[^;]+;|\+ *sourceURL/g, '');
|
||||
|
||||
// minify internal properties used by 'compareAscending' and `_.sortBy`
|
||||
// minify internal properties
|
||||
(function() {
|
||||
var properties = ['criteria', 'index', 'value'],
|
||||
snippets = source.match(/( +)function (?:compareAscending|sortBy)\b[\s\S]+?\n\1}/g);
|
||||
var methods = [
|
||||
'compareAscending',
|
||||
'createCache',
|
||||
'difference',
|
||||
'getObject',
|
||||
'intersection',
|
||||
'releaseObject',
|
||||
'sortBy',
|
||||
'uniq'
|
||||
];
|
||||
|
||||
var props = [
|
||||
'array',
|
||||
'cache',
|
||||
'contains',
|
||||
'criteria',
|
||||
'index',
|
||||
'indexOf',
|
||||
'initArray',
|
||||
'release',
|
||||
'value'
|
||||
];
|
||||
|
||||
var snippets = source.match(RegExp('^( +)(?:var|function) +(?:' + methods.join('|') + ')\\b[\\s\\S]+?\\n\\1}', 'gm'));
|
||||
if (!snippets) {
|
||||
return;
|
||||
}
|
||||
@@ -324,11 +345,12 @@
|
||||
var modified = snippet;
|
||||
|
||||
// minify properties
|
||||
properties.forEach(function(property, index) {
|
||||
var minName = minNames[index],
|
||||
reBracketProp = RegExp("\\['(" + property + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + property + '\\b', 'g'),
|
||||
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + property + "\\2 *:", 'g');
|
||||
props.forEach(function(prop, index) {
|
||||
// use minified names different than those chosen for `iteratorOptions`
|
||||
var minName = minNames[iteratorOptions.length + index],
|
||||
reBracketProp = RegExp("\\['(" + prop + ")'\\]", 'g'),
|
||||
reDotProp = RegExp('\\.' + prop + '\\b', 'g'),
|
||||
rePropColon = RegExp("([^?\\s])\\s*([\"'])?\\b" + prop + "\\2 *:", 'g');
|
||||
|
||||
modified = modified
|
||||
.replace(reBracketProp, "['" + minName + "']")
|
||||
@@ -352,8 +374,8 @@
|
||||
'createIterator\\((?:{|[a-zA-Z]+)[\\s\\S]*?\\);\\n',
|
||||
// match variables storing `createIterator` options
|
||||
'( +)var [a-zA-Z]+IteratorOptions\\b[\\s\\S]+?\\n\\2}',
|
||||
// match the the `createIterator` function
|
||||
'( +)function createIterator\\b[\\s\\S]+?\\n\\3}'
|
||||
// match the `createIterator`, `getObject`, and `releaseObject` functions
|
||||
'( +)function (?:createIterator|getObject|releaseObject)\\b[\\s\\S]+?\\n\\3}'
|
||||
].join('|'), 'g')
|
||||
);
|
||||
|
||||
@@ -363,7 +385,7 @@
|
||||
}
|
||||
|
||||
snippets.forEach(function(snippet, index) {
|
||||
var isCreateIterator = /function createIterator\b/.test(snippet),
|
||||
var isFunc = /^ *function +/m.test(snippet),
|
||||
isIteratorTemplate = /var iteratorTemplate\b/.test(snippet),
|
||||
modified = snippet;
|
||||
|
||||
@@ -392,8 +414,8 @@
|
||||
var minName = minNames[index];
|
||||
|
||||
// minify variable names present in strings
|
||||
if (isCreateIterator) {
|
||||
modified = modified.replace(RegExp('(([\'"])[^\\n\\2]*?)\\b' + varName + '\\b(?=[^\\n\\2]*\\2[ ,+]+$)', 'gm'), '$1' + minName);
|
||||
if (isFunc) {
|
||||
modified = modified.replace(RegExp('(([\'"])[^\\n\\2]*?)\\b' + varName + '\\b(?=[^\\n\\2]*\\2[ ,+;]+$)', 'gm'), '$1' + minName);
|
||||
}
|
||||
// ensure properties in compiled strings aren't minified
|
||||
else {
|
||||
|
||||
288
lodash.js
288
lodash.js
@@ -23,6 +23,10 @@
|
||||
window = freeGlobal;
|
||||
}
|
||||
|
||||
/** Used to pool arrays and objects used internally */
|
||||
var arrayPool = [],
|
||||
objectPool = [];
|
||||
|
||||
/** Used to generate unique IDs */
|
||||
var idCounter = 0;
|
||||
|
||||
@@ -139,6 +143,74 @@
|
||||
'\u2029': 'u2029'
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an array from the array pool or creates a new one if the pool is empty.
|
||||
*
|
||||
* @private
|
||||
* @returns {Array} The array from the pool.
|
||||
*/
|
||||
function getArray() {
|
||||
return arrayPool.pop() || [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an object from the object pool or creates a new one if the pool is empty.
|
||||
*
|
||||
* @private
|
||||
* @returns {Object} The object from the pool.
|
||||
*/
|
||||
function getObject() {
|
||||
return objectPool.pop() || {
|
||||
'args': null,
|
||||
'array': null,
|
||||
'arrays': null,
|
||||
'contains': null,
|
||||
'criteria': null,
|
||||
'false': null,
|
||||
'firstArg': null,
|
||||
'function': null,
|
||||
'index': null,
|
||||
'indexOf': null,
|
||||
'init': null,
|
||||
'initArray': null,
|
||||
'null': null,
|
||||
'number': null,
|
||||
'object': null,
|
||||
'push': null,
|
||||
'release': null,
|
||||
'shadowedProps': null,
|
||||
'string': null,
|
||||
'support': null,
|
||||
'true': null,
|
||||
'undefined': null,
|
||||
'useHas': null,
|
||||
'useKeys': null,
|
||||
'value': null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the given `array` back to the array pool.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} [array] The array to release.
|
||||
*/
|
||||
function releaseArray(array) {
|
||||
array.length = 0;
|
||||
arrayPool.push(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the given `object` back to the object pool.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} [object] The object to release.
|
||||
*/
|
||||
function releaseObject(object) {
|
||||
object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
|
||||
objectPool.push(object);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -580,8 +652,8 @@
|
||||
// iterate own properties using `Object.keys`
|
||||
' <% if (useHas && useKeys) { %>\n' +
|
||||
' var ownIndex = -1,\n' +
|
||||
' ownProps = objectTypes[typeof iterable] ? keys(iterable) : [],\n' +
|
||||
' length = ownProps.length;\n\n' +
|
||||
' ownProps = objectTypes[typeof iterable] && keys(iterable),\n' +
|
||||
' length = ownProps ? ownProps.length : 0;\n\n' +
|
||||
' while (++ownIndex < length) {\n' +
|
||||
' index = ownProps[ownIndex];\n<%' +
|
||||
" if (conditions.length) { %> if (<%= conditions.join(' && ') %>) {\n <% } %>" +
|
||||
@@ -778,7 +850,6 @@
|
||||
return bound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function optimized to search large arrays for a given `value`,
|
||||
* starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
|
||||
@@ -788,42 +859,28 @@
|
||||
* @param {Mixed} value The value to search for.
|
||||
* @returns {Boolean} Returns `true`, if `value` is found, else `false`.
|
||||
*/
|
||||
function createCache(array) {
|
||||
array || (array = []);
|
||||
|
||||
var bailout,
|
||||
index = -1,
|
||||
indexOf = getIndexOf(),
|
||||
length = array.length,
|
||||
isLarge = length >= largeArraySize && lodash.indexOf != indexOf,
|
||||
objCache = {};
|
||||
|
||||
var caches = {
|
||||
'false': false,
|
||||
'function': false,
|
||||
'null': false,
|
||||
'number': {},
|
||||
'object': objCache,
|
||||
'string': {},
|
||||
'true': false,
|
||||
'undefined': false
|
||||
};
|
||||
var createCache = (function() {
|
||||
|
||||
function basicContains(value) {
|
||||
return indexOf(array, value) > -1;
|
||||
return this.indexOf(this.array, value) > -1;
|
||||
}
|
||||
|
||||
function basicPush(value) {
|
||||
array.push(value);
|
||||
this.array.push(value);
|
||||
}
|
||||
|
||||
function cacheContains(value) {
|
||||
var type = typeof value;
|
||||
var cache = this.cache,
|
||||
type = typeof value;
|
||||
|
||||
if (type == 'boolean' || value == null) {
|
||||
return caches[value];
|
||||
return cache[value];
|
||||
}
|
||||
var cache = caches[type] || (type = 'object', objCache),
|
||||
key = type == 'number' ? value : keyPrefix + value;
|
||||
if (type != 'number' && type != 'string') {
|
||||
type = 'object';
|
||||
}
|
||||
var key = type == 'number' ? value : keyPrefix + value;
|
||||
cache = cache[type] || (cache[type] = {});
|
||||
|
||||
return type == 'object'
|
||||
? (cache[key] ? basicIndexOf(cache[key], value) > -1 : false)
|
||||
@@ -831,12 +888,17 @@
|
||||
}
|
||||
|
||||
function cachePush(value) {
|
||||
var type = typeof value;
|
||||
var cache = this.cache,
|
||||
type = typeof value;
|
||||
|
||||
if (type == 'boolean' || value == null) {
|
||||
caches[value] = true;
|
||||
cache[value] = true;
|
||||
} else {
|
||||
var cache = caches[type] || (type = 'object', objCache),
|
||||
key = type == 'number' ? value : keyPrefix + value;
|
||||
if (type != 'number' && type != 'string') {
|
||||
type = 'object';
|
||||
}
|
||||
var key = type == 'number' ? value : keyPrefix + value;
|
||||
cache = cache[type] || (cache[type] = {});
|
||||
|
||||
if (type == 'object') {
|
||||
bailout = (cache[key] || (cache[key] = [])).push(value) == length;
|
||||
@@ -846,18 +908,49 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (isLarge) {
|
||||
while (++index < length) {
|
||||
cachePush(array[index]);
|
||||
}
|
||||
if (bailout) {
|
||||
isLarge = caches = objCache = null;
|
||||
function release() {
|
||||
var cache = this.cache;
|
||||
if (cache.initArray) {
|
||||
releaseArray(this.array);
|
||||
}
|
||||
releaseObject(cache);
|
||||
}
|
||||
return isLarge
|
||||
? { 'contains': cacheContains, 'push': cachePush }
|
||||
: { 'contains': basicContains, 'push': basicPush };
|
||||
}
|
||||
|
||||
return function(array) {
|
||||
var bailout,
|
||||
index = -1,
|
||||
initArray = !array && (array = getArray()),
|
||||
length = array.length,
|
||||
isLarge = length >= largeArraySize && lodash.indexOf != indexOf;
|
||||
|
||||
var cache = getObject();
|
||||
cache.initArray = initArray;
|
||||
cache['false'] = cache['function'] = cache['null'] = cache['true'] = cache['undefined'] = false;
|
||||
|
||||
var result = getObject();
|
||||
result.array = array;
|
||||
result.indexOf = getIndexOf();
|
||||
result.cache = cache;
|
||||
result.contains = cacheContains;
|
||||
result.push = cachePush;
|
||||
result.release = release;
|
||||
|
||||
if (isLarge) {
|
||||
while (++index < length) {
|
||||
result.push(array[index]);
|
||||
}
|
||||
if (bailout) {
|
||||
isLarge = false;
|
||||
result.release();
|
||||
}
|
||||
}
|
||||
if (!isLarge) {
|
||||
result.contains = basicContains;
|
||||
result.push = basicPush;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}());
|
||||
|
||||
/**
|
||||
* Creates compiled iteration functions.
|
||||
@@ -874,20 +967,17 @@
|
||||
* @returns {Function} Returns the compiled function.
|
||||
*/
|
||||
function createIterator() {
|
||||
var data = {
|
||||
// data properties
|
||||
'shadowedProps': shadowedProps,
|
||||
'support': support,
|
||||
var data = getObject();
|
||||
|
||||
// iterator options
|
||||
'arrays': '',
|
||||
'bottom': '',
|
||||
'init': 'iterable',
|
||||
'loop': '',
|
||||
'top': '',
|
||||
'useHas': true,
|
||||
'useKeys': !!keys
|
||||
};
|
||||
// data properties
|
||||
data.shadowedProps = shadowedProps;
|
||||
data.support = support;
|
||||
|
||||
// iterator options
|
||||
data.arrays = data.bottom = data.loop = data.top = '';
|
||||
data.init = 'iterable';
|
||||
data.useHas = true;
|
||||
data.useKeys = !!keys;
|
||||
|
||||
// merge options into a template data object
|
||||
for (var object, index = 0; object = arguments[index]; index++) {
|
||||
@@ -900,16 +990,19 @@
|
||||
|
||||
// create the function factory
|
||||
var factory = Function(
|
||||
'errorClass, errorProto, hasOwnProperty, isArguments, isArray, isString, ' +
|
||||
'keys, lodash, objectProto, objectTypes, nonEnumProps, stringClass, ' +
|
||||
'stringProto, toString',
|
||||
'errorClass, errorProto, hasOwnProperty, isArguments, isArray, ' +
|
||||
'isString, keys, lodash, objectProto, objectTypes, nonEnumProps, ' +
|
||||
'stringClass, stringProto, toString',
|
||||
'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
|
||||
);
|
||||
|
||||
releaseObject(data);
|
||||
|
||||
// return the compiled function
|
||||
return factory(
|
||||
errorClass, errorProto, hasOwnProperty, isArguments, isArray, isString,
|
||||
keys, lodash, objectProto, objectTypes, nonEnumProps, stringClass,
|
||||
stringProto, toString
|
||||
errorClass, errorProto, hasOwnProperty, isArguments, isArray,
|
||||
isString, keys, lodash, objectProto, objectTypes, nonEnumProps,
|
||||
stringClass, stringProto, toString
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1368,8 +1461,9 @@
|
||||
return ctor(result.source, reFlags.exec(result));
|
||||
}
|
||||
// check for circular references and return corresponding clone
|
||||
stackA || (stackA = []);
|
||||
stackB || (stackB = []);
|
||||
var initStack = !stackA;
|
||||
stackA || (stackA = getArray());
|
||||
stackB || (stackB = getArray());
|
||||
|
||||
var length = stackA.length;
|
||||
while (length--) {
|
||||
@@ -1399,6 +1493,10 @@
|
||||
result[key] = clone(objValue, deep, callback, undefined, stackA, stackB);
|
||||
});
|
||||
|
||||
if (initStack) {
|
||||
releaseArray(stackA);
|
||||
releaseArray(stackB);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1845,8 +1943,9 @@
|
||||
// assume cyclic structures are equal
|
||||
// the algorithm for detecting cyclic structures is adapted from ES 5.1
|
||||
// section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3)
|
||||
stackA || (stackA = []);
|
||||
stackB || (stackB = []);
|
||||
var initStack = !stackA;
|
||||
stackA || (stackA = getArray());
|
||||
stackB || (stackB = getArray());
|
||||
|
||||
var length = stackA.length;
|
||||
while (length--) {
|
||||
@@ -1908,6 +2007,10 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
if (initStack) {
|
||||
releaseArray(stackA);
|
||||
releaseArray(stackB);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2217,8 +2320,9 @@
|
||||
stackA = args[4],
|
||||
stackB = args[5];
|
||||
} else {
|
||||
stackA = [];
|
||||
stackB = [];
|
||||
var initStack = true;
|
||||
stackA = getArray();
|
||||
stackB = getArray();
|
||||
|
||||
// allows working with `_.reduce` and `_.reduceRight` without
|
||||
// using their `callback` arguments, `index|key` and `collection`
|
||||
@@ -2284,6 +2388,11 @@
|
||||
object[key] = value;
|
||||
});
|
||||
}
|
||||
|
||||
if (initStack) {
|
||||
releaseArray(stackA);
|
||||
releaseArray(stackB);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -3443,17 +3552,18 @@
|
||||
|
||||
callback = lodash.createCallback(callback, thisArg);
|
||||
forEach(collection, function(value, key, collection) {
|
||||
result[++index] = {
|
||||
'criteria': callback(value, key, collection),
|
||||
'index': index,
|
||||
'value': value
|
||||
};
|
||||
var object = result[++index] = getObject();
|
||||
object.criteria = callback(value, key, collection);
|
||||
object.index = index;
|
||||
object.value = value;
|
||||
});
|
||||
|
||||
length = result.length;
|
||||
result.sort(compareAscending);
|
||||
while (length--) {
|
||||
result[length] = result[length].value;
|
||||
var object = result[length];
|
||||
result[length] = object.value;
|
||||
releaseObject(object);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -3555,15 +3665,16 @@
|
||||
var index = -1,
|
||||
length = array ? array.length : 0,
|
||||
flattened = concat.apply(arrayProto, nativeSlice.call(arguments, 1)),
|
||||
contains = createCache(flattened).contains,
|
||||
cache = createCache(flattened),
|
||||
result = [];
|
||||
|
||||
while (++index < length) {
|
||||
var value = array[index];
|
||||
if (!contains(value)) {
|
||||
if (!cache.contains(value)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
cache.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3867,27 +3978,35 @@
|
||||
function intersection(array) {
|
||||
var args = arguments,
|
||||
argsLength = args.length,
|
||||
cache = createCache(),
|
||||
caches = {},
|
||||
caches = getArray(),
|
||||
index = -1,
|
||||
length = array ? array.length : 0,
|
||||
isLarge = length >= largeArraySize,
|
||||
result = [];
|
||||
|
||||
caches[0] = createCache();
|
||||
|
||||
outer:
|
||||
while (++index < length) {
|
||||
var value = array[index];
|
||||
var cache = caches[0],
|
||||
value = array[index];
|
||||
|
||||
if (!cache.contains(value)) {
|
||||
var argsIndex = argsLength;
|
||||
cache.push(value);
|
||||
while (--argsIndex) {
|
||||
if (!(caches[argsIndex] || (caches[argsIndex] = createCache(args[argsIndex]).contains))(value)) {
|
||||
cache = caches[argsIndex] || (caches[argsIndex] = createCache(args[argsIndex]));
|
||||
if (!cache.contains(value)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
while (argsLength--) {
|
||||
caches[argsLength].release();
|
||||
}
|
||||
releaseArray(caches);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4257,11 +4376,11 @@
|
||||
*/
|
||||
var uniq = overloadWrapper(function(array, isSorted, callback) {
|
||||
var index = -1,
|
||||
indexOf = getIndexOf(),
|
||||
length = array ? array.length : 0,
|
||||
isLarge = !isSorted && length >= largeArraySize,
|
||||
indexOf = isLarge || getIndexOf(),
|
||||
result = [],
|
||||
seen = isLarge ? createCache() : (callback ? [] : result);
|
||||
seen = isLarge ? createCache() : (callback ? getArray() : result);
|
||||
|
||||
while (++index < length) {
|
||||
var value = array[index],
|
||||
@@ -4277,6 +4396,11 @@
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
if (isLarge) {
|
||||
seen.release();
|
||||
} else if (callback) {
|
||||
releaseArray(seen);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user