Add Stack helpers.

This commit is contained in:
John-David Dalton
2015-10-03 22:41:06 -07:00
parent 940559fc76
commit d236e37652

118
lodash.js
View File

@@ -1727,13 +1727,19 @@
* Creates a map cache object to store key-value pairs. * Creates a map cache object to store key-value pairs.
* *
* @private * @private
* @param {Array} [values] The values to cache.
*/ */
function MapCache() { function MapCache(values) {
this.__data__ = { this.__data__ = {
'hash': new Hash, 'hash': new Hash,
'map': Map ? new Map : [], 'map': Map ? new Map : [],
'string': new Hash 'string': new Hash
}; };
var length = values ? values.length : 0;
while (length--) {
var entry = values[length];
this.set(entry[0], entry[1]);
}
} }
/** /**
@@ -1775,7 +1781,7 @@
* *
* @private * @private
* @name has * @name has
* @memberOf _.memoize.Cache * @memberOf MapCache
* @param {string} key The key of the entry to check. * @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/ */
@@ -1819,8 +1825,8 @@
* @param {Array} [values] The values to cache. * @param {Array} [values] The values to cache.
*/ */
function SetCache(values) { function SetCache(values) {
var length = values ? values.length : 0;
this.__data__ = new MapCache; this.__data__ = new MapCache;
var length = values ? values.length : 0;
while (length--) { while (length--) {
this.push(values[length]); this.push(values[length]);
} }
@@ -1869,6 +1875,94 @@
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
*/
function Stack() {
this.__data__ = { 'array': [], 'map': null };
}
/**
* Removes `key` and its value from the stack.
*
* @private
* @name delete
* @memberOf Stack
* @param {string} key The key of the value to remove.
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
*/
function stackDelete(key) {
var data = this.__data__,
array = data.array;
return array ? assocDelete(array, key) : data.map['delete'](key);
}
/**
* Gets the stack value for `key`.
*
* @private
* @name get
* @memberOf Stack
* @param {string} key The key of the value to get.
* @returns {*} Returns the entry value.
*/
function stackGet(key) {
var data = this.__data__,
array = data.array;
return array ? assocGet(array, key) : data.map.get(key);
}
/**
* Checks if a stack value for `key` exists.
*
* @private
* @name has
* @memberOf Stack
* @param {string} key The key of the entry to check.
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
*/
function stackHas(key) {
var data = this.__data__,
array = data.array;
return array ? assocHas(array, key) : data.map.has(key);
}
/**
* Sets the stack `key` to `value`.
*
* @private
* @name set
* @memberOf Stack
* @param {string} key The key of the value to set.
* @param {*} value The value to set.
* @returns {Object} Returns the stack cache object.
*/
function stackSet(key, value) {
var data = this.__data__,
array = data.array;
if (array) {
if (array.length < LARGE_ARRAY_SIZE) {
assocSet(array, key, value);
} else {
data.array = null;
data.map = new MapCache(array);
}
}
var map = data.map;
if (map) {
map.set(key, value);
}
return this;
}
/*------------------------------------------------------------------------*/
/** /**
* Removes `key` and its value from the associative array. * Removes `key` and its value from the associative array.
* *
@@ -2082,7 +2176,7 @@
} }
} }
// Check for circular references and return its corresponding clone. // Check for circular references and return its corresponding clone.
stack || (stack = new MapCache); stack || (stack = new Stack);
var stacked = stack.get(value); var stacked = stack.get(value);
if (stacked) { if (stacked) {
return stacked; return stacked;
@@ -2511,7 +2605,7 @@
} }
// Assume cyclic values are equal. // Assume cyclic values are equal.
// For more information on detecting circular references see https://es5.github.io/#JO. // For more information on detecting circular references see https://es5.github.io/#JO.
stack || (stack = new MapCache); stack || (stack = new Stack);
var stacked = stack.get(object); var stacked = stack.get(object);
if (stacked) { if (stacked) {
return stacked == other; return stacked == other;
@@ -2563,7 +2657,7 @@
return false; return false;
} }
} else { } else {
var stack = new MapCache, var stack = new Stack,
result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) { if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
@@ -2716,7 +2810,7 @@
srcValue = source[key]; srcValue = source[key];
} }
if (isObject(srcValue)) { if (isObject(srcValue)) {
stack || (stack = new MapCache); stack || (stack = new Stack);
baseMergeDeep(object, source, key, baseMerge, customizer, stack); baseMergeDeep(object, source, key, baseMerge, customizer, stack);
} }
else { else {
@@ -12269,15 +12363,21 @@
// Avoid inheriting from `Object.prototype` when possible. // Avoid inheriting from `Object.prototype` when possible.
Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
// Add functions to the `MapCache` cache. // Add functions to the `MapCache`.
MapCache.prototype['delete'] = mapDelete; MapCache.prototype['delete'] = mapDelete;
MapCache.prototype.get = mapGet; MapCache.prototype.get = mapGet;
MapCache.prototype.has = mapHas; MapCache.prototype.has = mapHas;
MapCache.prototype.set = mapSet; MapCache.prototype.set = mapSet;
// Add functions to the `Set` cache. // Add functions to the `SetCache`.
SetCache.prototype.push = cachePush; SetCache.prototype.push = cachePush;
// Add functions to the `Stack` cache.
Stack.prototype['delete'] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;
// Assign cache to `_.memoize`. // Assign cache to `_.memoize`.
memoize.Cache = MapCache; memoize.Cache = MapCache;