mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 15:27:50 +00:00
This commit is contained in:
committed by
John-David Dalton
parent
71de0f2d08
commit
461b294bc7
267
lodash.js
267
lodash.js
@@ -34,17 +34,6 @@
|
||||
/** Used as the TypeError message for "Functions" methods */
|
||||
var FUNC_ERROR_TEXT = 'Expected a function';
|
||||
|
||||
/** Used as references for the max length and index of an array */
|
||||
var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1,
|
||||
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
|
||||
|
||||
/**
|
||||
* Used as the maximum length of an array-like value.
|
||||
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
|
||||
* for more details.
|
||||
*/
|
||||
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
|
||||
|
||||
/** Used as the internal argument placeholder */
|
||||
var PLACEHOLDER = '__lodash_placeholder__';
|
||||
|
||||
@@ -978,9 +967,24 @@
|
||||
nativeParseInt = context.parseInt,
|
||||
nativeRandom = Math.random;
|
||||
|
||||
/** Used as references for `-Infinity` and `Infinity` */
|
||||
var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY,
|
||||
POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
|
||||
|
||||
/** Used as references for the max length and index of an array */
|
||||
var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1,
|
||||
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
|
||||
|
||||
/** Used as the size, in bytes, of each Float64Array element */
|
||||
var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
|
||||
|
||||
/**
|
||||
* Used as the maximum length of an array-like value.
|
||||
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
|
||||
* for more details.
|
||||
*/
|
||||
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
|
||||
|
||||
/** Used to store function metadata */
|
||||
var metaMap = WeakMap && new WeakMap;
|
||||
|
||||
@@ -1084,29 +1088,14 @@
|
||||
*/
|
||||
function lodash(value) {
|
||||
if (value && typeof value == 'object') {
|
||||
if (value instanceof lodashWrapper) {
|
||||
if (value instanceof LodashWrapper) {
|
||||
return value;
|
||||
}
|
||||
if (!isArray(value) && hasOwnProperty.call(value, '__wrapped__')) {
|
||||
return new lodashWrapper(value.__wrapped__, value.__chain__, baseSlice(value.__queue__));
|
||||
return new LodashWrapper(value.__wrapped__, value.__chain__, baseSlice(value.__queue__));
|
||||
}
|
||||
}
|
||||
return new lodashWrapper(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* A fast path for creating `lodash` wrapper objects.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to wrap in a `lodash` instance.
|
||||
* @param {boolean} [chainAll=false] Enable chaining for all methods.
|
||||
* @param {Array} [queue=[]] Actions to peform to resolve the unwrapped value.
|
||||
* @returns {Object} Returns a `lodash` instance.
|
||||
*/
|
||||
function lodashWrapper(value, chainAll, queue) {
|
||||
this.__chain__ = !!chainAll;
|
||||
this.__queue__ = queue || [];
|
||||
this.__wrapped__ = value;
|
||||
return new LodashWrapper(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1206,8 +1195,7 @@
|
||||
support.nonEnumShadows = !/valueOf/.test(props);
|
||||
|
||||
/**
|
||||
* Detect if own properties are iterated after inherited properties
|
||||
* (IE < 9).
|
||||
* Detect if own properties are iterated after inherited properties (IE < 9).
|
||||
*
|
||||
* @memberOf _.support
|
||||
* @type boolean
|
||||
@@ -4575,6 +4563,23 @@
|
||||
return interceptor.call(thisArg, value);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A fast path for creating `lodash` wrapper objects.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to wrap in a `lodash` instance.
|
||||
* @param {boolean} [chainAll=false] Enable chaining for all methods.
|
||||
* @param {Array} [queue=[]] Actions to peform to resolve the unwrapped value.
|
||||
* @returns {Object} Returns a `lodash` instance.
|
||||
*/
|
||||
function LodashWrapper(value, chainAll, queue) {
|
||||
this.__chain__ = !!chainAll;
|
||||
this.__queue__ = queue || [];
|
||||
this.__wrapped__ = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables explicit method chaining on the wrapper object.
|
||||
*
|
||||
@@ -4634,10 +4639,13 @@
|
||||
* // => [1, 2, 3]
|
||||
*/
|
||||
function wrapperValueOf() {
|
||||
var result = this.__wrapped__;
|
||||
if (result instanceof lazyWrapper) {
|
||||
return result.value();
|
||||
}
|
||||
var index = -1,
|
||||
queue = this.__queue__,
|
||||
length = queue.length,
|
||||
result = this.__wrapped__;
|
||||
length = queue.length;
|
||||
|
||||
while (++index < length) {
|
||||
var args = [result],
|
||||
@@ -4652,6 +4660,142 @@
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
function limitSource(operators, source) {
|
||||
var len = operators.length,
|
||||
min = 0,
|
||||
max = source.length - 1;
|
||||
|
||||
for(var i = 0; i < len; i++) {
|
||||
var op = operators[i];
|
||||
switch(op.name) {
|
||||
case 'take': max = Math.min(max, min + (op.count - 1)); break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
min: min,
|
||||
max: max
|
||||
};
|
||||
}
|
||||
|
||||
function resolveLazyWrapper(wrapper, source, sourceRange) {
|
||||
var resultIndex = 0,
|
||||
dir = wrapper.dir,
|
||||
loops = sourceRange.max - sourceRange.min + 1,
|
||||
resultLimit = Math.min(wrapper.limit, loops),
|
||||
sourceIndex = (dir == 1 ? sourceRange.min : sourceRange.max) - dir,
|
||||
result = [],
|
||||
type = wrapper.type,
|
||||
iterators = wrapper.iterators,
|
||||
num = type.length;
|
||||
|
||||
lazy:
|
||||
while (loops-- && resultIndex < resultLimit) {
|
||||
sourceIndex += dir;
|
||||
val = source[sourceIndex];
|
||||
|
||||
for(i = 0; i < num; i++) {
|
||||
iterator = iterators[i];
|
||||
switch(type[i]) {
|
||||
// LazyWrapper.MAP_FLAG
|
||||
case 1: val = iterator(val, sourceIndex, source); break;
|
||||
// LazyWrapper.FILTER_FLAG
|
||||
case 2: if(!iterator(val, sourceIndex, source)) { continue lazy; }
|
||||
// LazyWrapper.WHILE_FLAG
|
||||
case 3: if(!iterator(val, sourceIndex, source)) { break lazy; }
|
||||
}
|
||||
}
|
||||
|
||||
result[resultIndex++] = val;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function LazyWrapper(value) {
|
||||
this.value = value;
|
||||
this.queue = [];
|
||||
|
||||
|
||||
|
||||
this.limit = POSITIVE_INFINITY;
|
||||
this.filterApplied = false;
|
||||
this.dir = 1;
|
||||
}
|
||||
|
||||
LodashWrapper(value, chainAll, queue) {
|
||||
this.__chain__ = !!chainAll;
|
||||
this.__queue__ = queue || [];
|
||||
this.__wrapped__ = value;
|
||||
}
|
||||
|
||||
/*
|
||||
this.type = [];
|
||||
this.iterators = [];
|
||||
this.limitActions = [];
|
||||
limitActions = [];
|
||||
*/
|
||||
|
||||
function lazyClone() {
|
||||
var clone = new LazyWrapper(this.source);
|
||||
clone.type = this.type.concat();
|
||||
clone.iterators = this.iterators.concat();
|
||||
clone.limit = this.limit;
|
||||
clone.limitActions = this.limitActions.concat();
|
||||
clone.filterApplied = this.filterApplied;
|
||||
clone.dir = this.dir;
|
||||
return clone;
|
||||
}
|
||||
|
||||
function lazyFilter(predicate, thisArg) {
|
||||
predicate = getCallback(predicate, thisArg, 3);
|
||||
|
||||
var fork = this.clone();
|
||||
fork.filterApplied = true;
|
||||
[methodName, object, arguments]
|
||||
fork.type.push(LazyWrapper.FILTER_FLAG);
|
||||
fork.iterators.push(predicate);
|
||||
return fork;
|
||||
}
|
||||
|
||||
function lazyFirst() {
|
||||
return this.take(1).value()[0];
|
||||
}
|
||||
|
||||
function lazyMap(iterator, thisArg) {
|
||||
iterator = getCallback(iterator, thisArg, 3);
|
||||
|
||||
var result = this.clone();
|
||||
result.queue.push([iterator);
|
||||
fork.type.push(LazyWrapper.MAP_FLAG);
|
||||
return fork;
|
||||
}
|
||||
|
||||
function lazyTake(n) {
|
||||
var fork = this.clone();
|
||||
n = (n == null) ? 1 : n;
|
||||
if(fork.filterApplied) {
|
||||
fork.limit = n;
|
||||
return new LazyWrapper(fork);
|
||||
}
|
||||
fork.limitActions.push(getLimitAction('take', n, this.dir));
|
||||
return fork;
|
||||
}
|
||||
|
||||
function lazyValue() {
|
||||
var source = this.source,
|
||||
sourceLimit;
|
||||
|
||||
if (source instanceof LazyWrapper) {
|
||||
source = source.value();
|
||||
}
|
||||
sourceLimit = limitSource(this.limitActions, source);
|
||||
console.log('sourceLimit', sourceLimit)
|
||||
return resolveLazyWrapper(this, source, sourceLimit);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Creates an array of elements corresponding to the specified keys, or indexes,
|
||||
* of the collection. Keys may be specified as individual arguments or as arrays
|
||||
@@ -5228,7 +5372,7 @@
|
||||
function max(collection, iteratee, thisArg) {
|
||||
iteratee = isIterateeCall(collection, iteratee, thisArg) ? null : iteratee;
|
||||
|
||||
var computed = -Infinity,
|
||||
var computed = NEGATIVE_INFINITY,
|
||||
noIteratee = iteratee == null,
|
||||
isArr = noIteratee && isArray(collection),
|
||||
isStr = !isArr && isString(collection),
|
||||
@@ -5252,7 +5396,7 @@
|
||||
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
var current = iteratee(value, index, collection);
|
||||
if (current > computed || (current === -Infinity && current === result)) {
|
||||
if (current > computed || (current === NEGATIVE_INFINITY && current === result)) {
|
||||
computed = current;
|
||||
result = value;
|
||||
}
|
||||
@@ -5307,7 +5451,7 @@
|
||||
function min(collection, iteratee, thisArg) {
|
||||
iteratee = isIterateeCall(collection, iteratee, thisArg) ? null : iteratee;
|
||||
|
||||
var computed = Infinity,
|
||||
var computed = POSITIVE_INFINITY,
|
||||
noIteratee = iteratee == null,
|
||||
isArr = noIteratee && isArray(collection),
|
||||
isStr = !isArr && isString(collection),
|
||||
@@ -5331,7 +5475,7 @@
|
||||
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
var current = iteratee(value, index, collection);
|
||||
if (current < computed || (current === Infinity && current === result)) {
|
||||
if (current < computed || (current === POSITIVE_INFINITY && current === result)) {
|
||||
computed = current;
|
||||
result = value;
|
||||
}
|
||||
@@ -9722,25 +9866,35 @@
|
||||
*/
|
||||
lodash.VERSION = VERSION;
|
||||
|
||||
// ensure `new lodashWrapper` is an instance of `lodash`
|
||||
lodashWrapper.prototype = lodash.prototype;
|
||||
|
||||
// add "Chaining" functions to the wrapper
|
||||
lodash.prototype.chain = wrapperChain;
|
||||
lodash.prototype.toString = wrapperToString;
|
||||
lodash.prototype.toJSON = lodash.prototype.value = lodash.prototype.valueOf = wrapperValueOf;
|
||||
|
||||
// assign default placeholders
|
||||
arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
|
||||
lodash[methodName].placeholder = lodash;
|
||||
});
|
||||
|
||||
// add `LazyWrapper` functions
|
||||
arrayEach(['map', 'filter', 'first', 'take'], function(methodName) {
|
||||
var func = LazyWrapper.prototype[methodName];
|
||||
var overriddenFunc = lodash.prototype[methodName];
|
||||
lodash.prototype[methodName] = function() {
|
||||
var isLazy = wrapped instanceof LazyWrapper,
|
||||
value = this.__wrapped__;
|
||||
|
||||
var result = isLazy
|
||||
? overriddenFunc.apply(this, arguments)
|
||||
: func.apply(inLazyChain ? wrapped : new LazyWrapper(wrapped), arguments);
|
||||
|
||||
return (wrapped instanceof LazyWrapper || this.__chain__)
|
||||
? new LodashWrapper(wrapped, this.__chain__)
|
||||
: wrapped;
|
||||
};
|
||||
});
|
||||
|
||||
// add `Array.prototype` functions
|
||||
arrayEach(['concat', 'join', 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
||||
var arrayFunc = arrayProto[methodName],
|
||||
retUnwrapped = /^(?:join|pop|shift)$/.test(methodName),
|
||||
chainName = /^(?:push|reverse|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
|
||||
fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName);
|
||||
fixObjects = !support.spliceObjects && /^(?:pop|shift|splice)$/.test(methodName),
|
||||
retUnwrapped = /^(?:join|pop|shift)$/.test(methodName);
|
||||
|
||||
// avoid array-like object bugs with `Array#shift` and `Array#splice` in
|
||||
// IE < 9, Firefox < 10, Narwhal, and RingoJS
|
||||
@@ -9763,6 +9917,25 @@
|
||||
};
|
||||
});
|
||||
|
||||
// add functions to the lazy wrapper
|
||||
LazyWrapper.prototype.clone = lazyClone;
|
||||
LazyWrapper.prototype.first = lazyFirst;
|
||||
LazyWrapper.prototype.map = lazyMap;
|
||||
LazyWrapper.prototype.take = lazyTake;
|
||||
LazyWrapper.prototype.value = lazyValue;
|
||||
|
||||
// ensure `new LodashWrapper` is an instance of `lodash`
|
||||
LodashWrapper.prototype = lodash.prototype;
|
||||
|
||||
// add function aliases to the lodash wrapper
|
||||
lodash.prototype.collect = lodash.prototype.map;
|
||||
lodash.prototype.select = lodash.prototype.filter;
|
||||
|
||||
// add "Chaining" functions to the lodash wrapper
|
||||
lodash.prototype.chain = wrapperChain;
|
||||
lodash.prototype.toString = wrapperToString;
|
||||
lodash.prototype.toJSON = lodash.prototype.value = lodash.prototype.valueOf = wrapperValueOf;
|
||||
|
||||
return lodash;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user