问题
I am trying to have search for Underscore equivalent for Lodash _.get
and _.has
, where it is able to directly access the existence and value of nested object value without the need of checking the existence of its parents.
However, it seems to me that underscore _.get
and _.has
only able to check the value for the first level.
var object = { 'a': { 'b': 2 } };
_.has(object, 'a.b'); // lodash shows true
_.has(object, 'a.b'); // underscore shows false
回答1:
As far as I know, undercore doesn't perform a deep search, so you'll have to settle for shallow has
and get
(or change to lodash).
You can also try to implement it yourself (you can check lodash's implementation and try to copy it or come up with your own solution).
This is a simple solution to the has
problem (get
would be similar), using recursion and the current underscore has
's implementation.
Hope it helps.
var a = {
a: 1,
b: {
a: { c: { d: 1 }}
}
};
var hasDeep = function(obj, path) {
if(!path) return true;
var paths = path.split('.'),
nPath = _.first(paths);
return _.has(obj, nPath) && hasDeep(obj[nPath], _.rest(paths).join('.'));
}
console.log(hasDeep(a, 'b.a.c.d'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
回答2:
use underscore.get module
const {get} = require('underscore.get');
Underscore.Get
回答3:
You can add an extension to underscore with your custom method via _.mixin
this is the mixin that works like a _.get
of lodash
passing the chain of the object to evaluate i.e.
Usage
_.get(a, 'a[0].b');
"collectionValue1" // you will get
Mixin
_.mixin({
get: function(obj, path) {
if (!obj && !path) {
return undefined;
} else {
var paths;
if (!_.isEmpty(path.match(/^\[\d\]/))) {
paths = path.replace(/^[\[\]]/g, '').split(/\./);
nPath = _.first(paths[0].replace(/\]/, ''));
} else {
paths = path.split(/[\.\[]/);
nPath = _.first(paths);
}
remainingPath = _.reduce(_.rest(paths), function(result, item) {
if (!_.isEmpty(item)) {
if (item.match(/^\d\]/)) {
item = "[" + item;
}
result.push(item);
}
return result;
}, []).join('.');
if (_.isEmpty(remainingPath)) {
return obj[nPath];
} else {
return _.has(obj, nPath) && _.get(obj[nPath], remainingPath);
}
}
}
});
Take a look to the sample
var a = {
a: [
{ b: "collectionValue1" },
{ b: "collectionValue2", list: [ { item: "listValue1" }, { item: [{value: "Working"}] }] }
],
b: {
a: {
c: {
d:"success"
}
}
}
};
_.mixin({
get: function(obj, path) {
if (!obj && !path) {
return undefined;
} else {
var paths;
if (!_.isEmpty(path.match(/^\[\d\]/))) {
paths = path.replace(/^[\[\]]/g, '').split(/\./);
nPath = _.first(paths[0].replace(/\]/, ''));
} else {
paths = path.split(/[\.\[]/);
nPath = _.first(paths);
}
remainingPath = _.reduce(_.rest(paths), function(result, item) {
if (!_.isEmpty(item)) {
if (item.match(/^\d\]/)) {
item = "[" + item;
}
result.push(item);
}
return result;
}, []).join('.');
if (_.isEmpty(remainingPath)) {
return obj[nPath];
} else {
return _.has(obj, nPath) && _.get(obj[nPath], remainingPath);
}
}
}
});
console.log(_.get(a, 'a[0].b'));
console.log(_.get(a, 'b.a.c.d'));
console.log(_.get(a, 'a[1].b'));
console.log(_.get(a, 'a[1].list[0].item'));
console.log(_.get(a, 'a[1].list[1].item[0].value'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
来源:https://stackoverflow.com/questions/42042245/underscore-equivalent-of-lodash-get-and-has