mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-12 03:47:50 +00:00
Add _.hasIn and more path helper functions.
This commit is contained in:
186
lodash.js
186
lodash.js
@@ -1986,6 +1986,30 @@
|
|||||||
return (index && index == length) ? object : undefined;
|
return (index && index == length) ? object : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.has` without support for deep paths.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @param {Array|string} key The key to check.
|
||||||
|
* @returns {boolean} Returns `true` if `key` is a property, else `false`.
|
||||||
|
*/
|
||||||
|
function baseHas(object, key) {
|
||||||
|
return object != null && hasOwnProperty.call(object, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base implementation of `_.hasIn` without support for deep paths.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @param {Array|string} key The key to check.
|
||||||
|
* @returns {boolean} Returns `true` if `key` is a property, else `false`.
|
||||||
|
*/
|
||||||
|
function baseHasIn(object, key) {
|
||||||
|
return object != null && key in Object(object);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.isEqual` which supports partial comparisons
|
* The base implementation of `_.isEqual` which supports partial comparisons
|
||||||
* and tracks traversed objects.
|
* and tracks traversed objects.
|
||||||
@@ -2240,25 +2264,11 @@
|
|||||||
* @returns {Function} Returns the new function.
|
* @returns {Function} Returns the new function.
|
||||||
*/
|
*/
|
||||||
function baseMatchesProperty(path, srcValue) {
|
function baseMatchesProperty(path, srcValue) {
|
||||||
var isCommon = isKey(path) && isStrictComparable(srcValue),
|
|
||||||
pathKey = (path + '');
|
|
||||||
|
|
||||||
path = toPath(path);
|
|
||||||
return function(object) {
|
return function(object) {
|
||||||
if (object == null) {
|
var objValue = get(object, path);
|
||||||
return false;
|
return (objValue === undefined && objValue === srcValue)
|
||||||
}
|
? hasIn(object, path)
|
||||||
var key = pathKey;
|
: baseIsEqual(srcValue, objValue, undefined, true);
|
||||||
if (!isCommon && !(key in Object(object))) {
|
|
||||||
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
||||||
if (object == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
key = last(path);
|
|
||||||
}
|
|
||||||
return object[key] === srcValue
|
|
||||||
? (srcValue !== undefined || (key in Object(object)))
|
|
||||||
: baseIsEqual(srcValue, object[key], undefined, true);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2442,7 +2452,7 @@
|
|||||||
}
|
}
|
||||||
else if (!isKey(index, array)) {
|
else if (!isKey(index, array)) {
|
||||||
var path = toPath(index),
|
var path = toPath(index),
|
||||||
object = path.length == 1 ? array : baseGet(array, baseSlice(path, 0, -1));
|
object = parent(array, path);
|
||||||
|
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
delete object[last(path)];
|
delete object[last(path)];
|
||||||
@@ -3763,6 +3773,33 @@
|
|||||||
return { 'start': start, 'end': end };
|
return { 'start': start, 'end': end };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `path` exists on `object`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @param {Array|string} path The path to check.
|
||||||
|
* @param {Function} hasFunc The function to check properties.
|
||||||
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||||||
|
*/
|
||||||
|
function hasPath(object, path, hasFunc) {
|
||||||
|
if (object == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
object = Object(object);
|
||||||
|
var result = hasFunc(object, path);
|
||||||
|
if (!result && !isKey(path)) {
|
||||||
|
path = toPath(path);
|
||||||
|
object = parent(object, path);
|
||||||
|
if (object != null) {
|
||||||
|
path = last(path);
|
||||||
|
result = hasFunc(object, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result || (isLength(object && object.length) && isIndex(path, object.length) &&
|
||||||
|
(isArray(object) || isArguments(object) || isString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an array clone.
|
* Initializes an array clone.
|
||||||
*
|
*
|
||||||
@@ -3866,9 +3903,9 @@
|
|||||||
* @returns {*} Returns the result of the invoked method.
|
* @returns {*} Returns the result of the invoked method.
|
||||||
*/
|
*/
|
||||||
function invokePath(object, path, args) {
|
function invokePath(object, path, args) {
|
||||||
if (object != null && !isKey(path, object)) {
|
if (!isKey(path, object)) {
|
||||||
path = toPath(path);
|
path = toPath(path);
|
||||||
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
|
object = parent(object, path);
|
||||||
path = last(path);
|
path = last(path);
|
||||||
}
|
}
|
||||||
var func = object == null ? object : object[path];
|
var func = object == null ? object : object[path];
|
||||||
@@ -3933,15 +3970,12 @@
|
|||||||
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
||||||
*/
|
*/
|
||||||
function isKey(value, object) {
|
function isKey(value, object) {
|
||||||
var type = typeof value;
|
if (typeof value == 'number') {
|
||||||
if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isArray(value)) {
|
return !isArray(value) &&
|
||||||
return false;
|
(reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
||||||
}
|
(object != null && value in Object(object)));
|
||||||
var result = !reIsDeepProp.test(value);
|
|
||||||
return result || (object != null && value in Object(object));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4091,6 +4125,18 @@
|
|||||||
return objValue === undefined ? srcValue : objValue;
|
return objValue === undefined ? srcValue : objValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parent value at `path` of `object`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Object} object The object to query.
|
||||||
|
* @param {Array} path The path to get the parent value of.
|
||||||
|
* @returns {*} Returns the parent value.
|
||||||
|
*/
|
||||||
|
function parent(object, path) {
|
||||||
|
return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reorder `array` according to the specified indexes where the element at
|
* Reorder `array` according to the specified indexes where the element at
|
||||||
* the first index is assigned as the first element, the element at
|
* the first index is assigned as the first element, the element at
|
||||||
@@ -8930,17 +8976,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if `path` is a direct property.
|
* Checks if `path` is a direct property of `object`.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
* @category Object
|
* @category Object
|
||||||
* @param {Object} object The object to query.
|
* @param {Object} object The object to query.
|
||||||
* @param {Array|string} path The path to check.
|
* @param {Array|string} path The path to check.
|
||||||
* @returns {boolean} Returns `true` if `path` is a direct property, else `false`.
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* var object = { 'a': { 'b': { 'c': 3 } } };
|
* var object = { 'a': { 'b': { 'c': 3 } } },
|
||||||
|
* other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
|
||||||
*
|
*
|
||||||
* _.has(object, 'a');
|
* _.has(object, 'a');
|
||||||
* // => true
|
* // => true
|
||||||
@@ -8950,23 +8997,41 @@
|
|||||||
*
|
*
|
||||||
* _.has(object, ['a', 'b', 'c']);
|
* _.has(object, ['a', 'b', 'c']);
|
||||||
* // => true
|
* // => true
|
||||||
|
*
|
||||||
|
* _.has(other, 'a');
|
||||||
|
* // => false
|
||||||
*/
|
*/
|
||||||
function has(object, path) {
|
function has(object, path) {
|
||||||
if (object == null) {
|
return hasPath(object, path, baseHas);
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
var result = hasOwnProperty.call(object, path);
|
/**
|
||||||
if (!result && !isKey(path)) {
|
* Checks if `path` is a direct or inherited property of `object`.
|
||||||
path = toPath(path);
|
*
|
||||||
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
|
* @static
|
||||||
if (object == null) {
|
* @memberOf _
|
||||||
return false;
|
* @category Object
|
||||||
}
|
* @param {Object} object The object to query.
|
||||||
path = last(path);
|
* @param {Array|string} path The path to check.
|
||||||
result = hasOwnProperty.call(object, path);
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
||||||
}
|
* @example
|
||||||
return result || (isLength(object.length) && isIndex(path, object.length) &&
|
*
|
||||||
(isArray(object) || isArguments(object) || isString(object)));
|
* var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
|
||||||
|
*
|
||||||
|
* _.hasIn(object, 'a');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* _.hasIn(object, 'a.b.c');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* _.hasIn(object, ['a', 'b', 'c']);
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* _.hasIn(object, 'b');
|
||||||
|
* // => false
|
||||||
|
*/
|
||||||
|
function hasIn(object, path) {
|
||||||
|
return hasPath(object, path, baseHasIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9387,23 +9452,22 @@
|
|||||||
* // => 'default'
|
* // => 'default'
|
||||||
*/
|
*/
|
||||||
function result(object, path, defaultValue) {
|
function result(object, path, defaultValue) {
|
||||||
var isPath = !isKey(path, object),
|
if (!isKey(path, object)) {
|
||||||
result = (isPath || object == null) ? undefined : object[path];
|
path = toPath(path);
|
||||||
|
var result = get(object, path);
|
||||||
|
object = parent(object, path);
|
||||||
|
} else {
|
||||||
|
result = object == null ? undefined : object[path];
|
||||||
|
}
|
||||||
if (result === undefined) {
|
if (result === undefined) {
|
||||||
if (object != null && isPath) {
|
result = defaultValue;
|
||||||
path = toPath(path);
|
|
||||||
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
||||||
result = object == null ? undefined : object[last(path)];
|
|
||||||
}
|
|
||||||
result = result === undefined ? defaultValue : result;
|
|
||||||
}
|
}
|
||||||
return isFunction(result) ? result.call(object) : result;
|
return isFunction(result) ? result.call(object) : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the property value of `path` on `object`. If a portion of `path`
|
* Sets the value at `path` of `object`. If a portion of `path` doesn't
|
||||||
* doesn't exist it's created.
|
* exist it's created.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -10663,8 +10727,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a function that compares the property value of `path` on a given
|
* Creates a function that compares the value at `path` on a given object
|
||||||
* object to `srcValue`.
|
* to `srcValue`.
|
||||||
*
|
*
|
||||||
* **Note:** This method supports comparing arrays, booleans, `Date` objects,
|
* **Note:** This method supports comparing arrays, booleans, `Date` objects,
|
||||||
* numbers, `Object` objects, regexes, and strings.
|
* numbers, `Object` objects, regexes, and strings.
|
||||||
@@ -10854,8 +10918,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a function that returns the property value at `path` on a
|
* Creates a function that returns the value at `path` on a given object.
|
||||||
* given object.
|
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -11448,6 +11511,7 @@
|
|||||||
lodash.gt = gt;
|
lodash.gt = gt;
|
||||||
lodash.gte = gte;
|
lodash.gte = gte;
|
||||||
lodash.has = has;
|
lodash.has = has;
|
||||||
|
lodash.hasIn = hasIn;
|
||||||
lodash.identity = identity;
|
lodash.identity = identity;
|
||||||
lodash.includes = includes;
|
lodash.includes = includes;
|
||||||
lodash.indexOf = indexOf;
|
lodash.indexOf = indexOf;
|
||||||
|
|||||||
@@ -17266,7 +17266,7 @@
|
|||||||
|
|
||||||
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
||||||
|
|
||||||
test('should accept falsey arguments', 222, function() {
|
test('should accept falsey arguments', 223, function() {
|
||||||
var emptyArrays = _.map(falsey, _.constant([]));
|
var emptyArrays = _.map(falsey, _.constant([]));
|
||||||
|
|
||||||
_.each(acceptFalsey, function(methodName) {
|
_.each(acceptFalsey, function(methodName) {
|
||||||
|
|||||||
Reference in New Issue
Block a user