相当于 Lodash _.get 和 _.has 的下划线
Underscore equivalent of Lodash _.get and _.has
我正在尝试搜索 Lodash _.get
和 _.has
的 Underscore 等效项,它可以直接访问嵌套 object 值的存在和值而不需要检查其 parents.
是否存在
但是,在我看来,下划线_.get
和_.has
只能检查第一级的值。
var object = { 'a': { 'b': 2 } };
_.has(object, 'a.b'); // lodash shows true
_.has(object, 'a.b'); // underscore shows false
据我所知,undercore 不执行深度搜索,因此您必须满足于浅层 has
和 get
(或更改为 lodash)。
你也可以尝试自己实现(你可以查看lodash的实现并尝试复制它或者想出你自己的解决方案)。
这是 has
问题的简单解决方案(get
类似),使用递归和当前下划线 has
的实现。
希望对您有所帮助。
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>
有一些外部库提供此功能:
- underscore-contrib
getPath()
- underscore-keypath
valueForKeyPath()
- underscore.get
get()
您可以通过 _.mixin
使用自定义方法添加下划线扩展
这是一个 mixin,其工作方式类似于 lodash
的 _.get
传递对象链以进行评估,即
用法
_.get(a, 'a[0].b');
"collectionValue1" // you will get
混音
_.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);
}
}
}
});
看看样本
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>
我正在尝试搜索 Lodash _.get
和 _.has
的 Underscore 等效项,它可以直接访问嵌套 object 值的存在和值而不需要检查其 parents.
但是,在我看来,下划线_.get
和_.has
只能检查第一级的值。
var object = { 'a': { 'b': 2 } };
_.has(object, 'a.b'); // lodash shows true
_.has(object, 'a.b'); // underscore shows false
据我所知,undercore 不执行深度搜索,因此您必须满足于浅层 has
和 get
(或更改为 lodash)。
你也可以尝试自己实现(你可以查看lodash的实现并尝试复制它或者想出你自己的解决方案)。
这是 has
问题的简单解决方案(get
类似),使用递归和当前下划线 has
的实现。
希望对您有所帮助。
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>
有一些外部库提供此功能:
- underscore-contrib
getPath()
- underscore-keypath
valueForKeyPath()
- underscore.get
get()
您可以通过 _.mixin
这是一个 mixin,其工作方式类似于 lodash
的 _.get
传递对象链以进行评估,即
用法
_.get(a, 'a[0].b');
"collectionValue1" // you will get
混音
_.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);
}
}
}
});
看看样本
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>