使用 Underscore.JS 深度采摘
Deep picking using Underscore.JS
我正在尝试使用 underscoreJs 来操作 JavaScript 对象,但在操作时遇到了问题。
这是我的例子
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
var res = _(data).chain().
pluck('parent').
flatten().
findWhere(function(item){
item === "user_get"
}).
value();
console.log(res);
使用属于 data.parent.calls[]
的元素(示例:"user_get")我想提取其父对象,即 data.parent[0]
。
我在上面尝试过,但总是得到 undefined。感谢您对此提供的任何帮助。
这似乎可以解决问题。
function findByCall(data, call) {
return _.find(data.parent, function(parent) { //From data.parent list, find an item that
return _.some(parent.resources, function(resource) {//has such parent.resource that it
return _.includes(resource.calls, call); //includes the searched resource.calls item
});
});
}
//Test
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
console.log(findByCall(data, 'user_get'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
您遇到的问题之一是您对 _.pluck
的使用。如果你在一个对象上执行 _.pluck
,它将遍历对象的键,试图检索你指定为第二个参数的 属性(在本例中,'parent')。 'label' 是一个字符串,'parent' 是一个数组,因此得到的数组是 [undefined, undefined]
。剩下的就出错了。
一种解决方案如下:
function findCallIndexInParent(call, parent) {
return _.chain(parent)
.pluck('resources')
.flatten()
.findIndex(function (obj) {
return _.contains(obj.calls, call);
})
.value();
}
function findCall(call, data) {
var parent = data.parent;
return parent[findCallIndexInParent(call, parent)];
}
console.log(findCall('user_get', data));
findCall
只是一种方便的方法,它将数据的父级 属性 传递给 findCallIndexInParent
(这将检索索引 call 是)和 return 具有 parent 数组的所需对象。
Lodash(下划线的一个分支)提供了一种获取对象的 属性 的方法,它在这里非常方便(遗憾的是,下划线没有)。
findCallIndexInParent
的解释如下:
- 链接父列表
- 提取资源数组
- 作为 pluck 映射,它 return 是一个列表列表,因此需要展平。
- 查找calls包含call
的元素的索引
- Return parent.
中包含 call 的对象的值(索引)
这是fiddle。希望对你有帮助。
如果我没理解错的话,你想获取 parent
数组中元素的索引,该数组具有指定调用的任何资源。
data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
}
// find the index of a parent
const index = _.findIndex(data.parent, parent =>
// that has any (some) resources
_.some(parent.resources, resource =>
// that contains 'user_get' call in its calls list
_.contains(resource.calls, 'user_get')
)
)
console.log(index) // 0
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
如果要查找实际的父对象,请使用 find
而不是 findIndex
如果要查找与此调用匹配的所有父对象,请使用 filter
而不是 findIndex
我正在尝试使用 underscoreJs 来操作 JavaScript 对象,但在操作时遇到了问题。
这是我的例子
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
var res = _(data).chain().
pluck('parent').
flatten().
findWhere(function(item){
item === "user_get"
}).
value();
console.log(res);
使用属于 data.parent.calls[]
的元素(示例:"user_get")我想提取其父对象,即 data.parent[0]
。
我在上面尝试过,但总是得到 undefined。感谢您对此提供的任何帮助。
这似乎可以解决问题。
function findByCall(data, call) {
return _.find(data.parent, function(parent) { //From data.parent list, find an item that
return _.some(parent.resources, function(resource) {//has such parent.resource that it
return _.includes(resource.calls, call); //includes the searched resource.calls item
});
});
}
//Test
var data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
};
console.log(findByCall(data, 'user_get'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
您遇到的问题之一是您对 _.pluck
的使用。如果你在一个对象上执行 _.pluck
,它将遍历对象的键,试图检索你指定为第二个参数的 属性(在本例中,'parent')。 'label' 是一个字符串,'parent' 是一个数组,因此得到的数组是 [undefined, undefined]
。剩下的就出错了。
一种解决方案如下:
function findCallIndexInParent(call, parent) {
return _.chain(parent)
.pluck('resources')
.flatten()
.findIndex(function (obj) {
return _.contains(obj.calls, call);
})
.value();
}
function findCall(call, data) {
var parent = data.parent;
return parent[findCallIndexInParent(call, parent)];
}
console.log(findCall('user_get', data));
findCall
只是一种方便的方法,它将数据的父级 属性 传递给 findCallIndexInParent
(这将检索索引 call 是)和 return 具有 parent 数组的所需对象。
Lodash(下划线的一个分支)提供了一种获取对象的 属性 的方法,它在这里非常方便(遗憾的是,下划线没有)。
findCallIndexInParent
的解释如下:
- 链接父列表
- 提取资源数组
- 作为 pluck 映射,它 return 是一个列表列表,因此需要展平。
- 查找calls包含call 的元素的索引
- Return parent. 中包含 call 的对象的值(索引)
这是fiddle。希望对你有帮助。
如果我没理解错的话,你想获取 parent
数组中元素的索引,该数组具有指定调用的任何资源。
data = {
"label": "SomeName",
"parent": [{
"id": "parentId",
"resources": [{
"name": "ID1NAME",
"calls": [
"user_get", "user2_post", "user3_delete"
]
}, {
"name": "ID2",
"calls": [
"employee1_get", "employee2_delete", "employee3_update"
]
}]
}]
}
// find the index of a parent
const index = _.findIndex(data.parent, parent =>
// that has any (some) resources
_.some(parent.resources, resource =>
// that contains 'user_get' call in its calls list
_.contains(resource.calls, 'user_get')
)
)
console.log(index) // 0
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
如果要查找实际的父对象,请使用 find
而不是 findIndex
如果要查找与此调用匹配的所有父对象,请使用 filter
而不是 findIndex