mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-12 20:07:49 +00:00
Add baseMergeDeep.
This commit is contained in:
committed by
jdalton
parent
e76f79cd56
commit
130fafd7c2
107
lodash.src.js
107
lodash.src.js
@@ -2479,61 +2479,79 @@
|
|||||||
* @returns {Object} Returns the destination object.
|
* @returns {Object} Returns the destination object.
|
||||||
*/
|
*/
|
||||||
function baseMerge(object, source, customizer, stackA, stackB) {
|
function baseMerge(object, source, customizer, stackA, stackB) {
|
||||||
var isSrcArr = isArray(source) || isTypedArray(source);
|
var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source));
|
||||||
|
|
||||||
(isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
(isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
||||||
var value = object[key];
|
if (isObjectLike(srcValue)) {
|
||||||
|
stackA || (stackA = []);
|
||||||
if (!isObjectLike(srcValue)) {
|
stackB || (stackB = []);
|
||||||
var result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
return baseMergeDeep(object, source, baseMerge, key, customizer, stackA, stackB);
|
||||||
isCommon = typeof result == 'undefined';
|
|
||||||
|
|
||||||
if (isCommon) {
|
|
||||||
result = srcValue;
|
|
||||||
}
|
|
||||||
if ((isSrcArr || typeof result != 'undefined') &&
|
|
||||||
(isCommon || (result === result ? result !== value : value === value))) {
|
|
||||||
object[key] = result;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// Avoid merging previously merged cyclic sources.
|
var value = object[key],
|
||||||
stackA || (stackA = []);
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
||||||
stackB || (stackB = []);
|
isCommon = typeof result == 'undefined';
|
||||||
|
|
||||||
var length = stackA.length;
|
|
||||||
while (length--) {
|
|
||||||
if (stackA[length] == srcValue) {
|
|
||||||
object[key] = stackB[length];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = customizer ? customizer(value, srcValue, key, object, source) : undefined;
|
|
||||||
isCommon = typeof result == 'undefined';
|
|
||||||
|
|
||||||
if (isCommon) {
|
if (isCommon) {
|
||||||
result = srcValue;
|
result = srcValue;
|
||||||
if (isArray(srcValue) || isTypedArray(srcValue)) {
|
|
||||||
result = isArray(value) ? value : [];
|
|
||||||
} else if (isPlainObject(srcValue)) {
|
|
||||||
result = isPlainObject(value) ? value : {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Add the source value to the stack of traversed objects and associate
|
if ((isSrcArr || typeof result != 'undefined') &&
|
||||||
// it with its merged value.
|
(isCommon || (result === result ? result !== value : value === value))) {
|
||||||
stackA.push(srcValue);
|
|
||||||
stackB.push(result);
|
|
||||||
|
|
||||||
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
||||||
if (isCommon) {
|
|
||||||
object[key] = baseMerge(result, srcValue, customizer, stackA, stackB);
|
|
||||||
} else if (result === result ? result !== value : value === value) {
|
|
||||||
object[key] = result;
|
object[key] = result;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
||||||
|
* deep merges and tracks traversed objects enabling objects with circular
|
||||||
|
* references to be merged.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The destination object.
|
||||||
|
* @param {Object} source The source object.
|
||||||
|
* @param {Function} mergeFunc The function to merge values.
|
||||||
|
* @param {string} key The key of the property value to merge.
|
||||||
|
* @param {Function} [customizer] The function to customize merging properties.
|
||||||
|
* @param {Array} [stackA=[]] Tracks traversed source objects.
|
||||||
|
* @param {Array} [stackB=[]] Associates values with source counterparts.
|
||||||
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||||||
|
*/
|
||||||
|
function baseMergeDeep(object, source, mergeFunc, key, customizer, stackA, stackB) {
|
||||||
|
var length = stackA.length,
|
||||||
|
srcValue = source[key];
|
||||||
|
|
||||||
|
while (length--) {
|
||||||
|
if (stackA[length] == srcValue) {
|
||||||
|
object[key] = stackB[length];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var value = object[key],
|
||||||
|
result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
|
||||||
|
isCommon = typeof result == 'undefined';
|
||||||
|
|
||||||
|
if (isCommon) {
|
||||||
|
result = srcValue;
|
||||||
|
if (isArray(srcValue) || isTypedArray(srcValue)) {
|
||||||
|
result = isArray(value) ? value : [];
|
||||||
|
} else if (isPlainObject(srcValue)) {
|
||||||
|
result = isPlainObject(value) ? value : {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add the source value to the stack of traversed objects and associate
|
||||||
|
// it with its merged value.
|
||||||
|
stackA.push(srcValue);
|
||||||
|
stackB.push(result);
|
||||||
|
|
||||||
|
if (isCommon) {
|
||||||
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
||||||
|
object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
|
||||||
|
} else if (result === result ? result !== value : value === value) {
|
||||||
|
object[key] = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.property` which does not coerce `key` to a string.
|
* The base implementation of `_.property` which does not coerce `key` to a string.
|
||||||
*
|
*
|
||||||
@@ -3034,7 +3052,10 @@
|
|||||||
}
|
}
|
||||||
var index = 0;
|
var index = 0;
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
assigner(object, arguments[index], customizer);
|
var source = arguments[index];
|
||||||
|
if (source) {
|
||||||
|
assigner(object, source, customizer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return object;
|
return object;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user