我有一个对象数组,我希望将其转换为键值对的映射,并以id
为键。但是,我想在根级别和recipes
属性中执行此操作。
数组resp
:
[
{
"id": "1",
"recipes": [
{
"id": 4036
},
{
"id": 4041
}
]
},
{
"id": "2",
"recipes": [
{
"id": 4052
},
{
"id": 4053
}
]
}
]
我遇到了_.keyBy()
,它将一个属性映射为键,但它不允许嵌套级别。
功能:
var respObj = _.keyBy(resp, 'id');
是否有一个优雅的解决方案来按摩resp
以使所有嵌套在数组中的对象都使用id
作为关键?
谢谢!
答案 0 :(得分:3)
这是一个通用的解决方案,在数组上递归运行_.keyBy
,以及它们内部的对象:
function deepKeyBy(arr, key) {
return _(arr)
.map(function(o) { // map each object in the array
return _.mapValues(o, function(v) { // map the properties of the object
return _.isArray(v) ? deepKeyBy(v, key) : v; // if the property value is an array, run deepKeyBy() on it
});
})
.keyBy(key); // index the object by the key
}
我在示例(成分)中添加了另一个级别的数据:
function deepKeyBy(arr, key) {
return _(arr)
.map(function(o) {
return _.mapValues(o, function(v) {
return _.isArray(v) ? deepKeyBy(v, key) : v;
});
})
.keyBy(key);
}
var arr = [{
"id": "1",
"recipes": [{
"id": 4036,
"ingerdients": [{
"id": 5555555
}, {
"id": 5555556
}, {
"id": 5555557
}]
}, {
"id": 4041
}]
}, {
"id": "2",
"recipes": [{
"id": 4052
}, {
"id": 4053
}]
}];
var result = deepKeyBy(arr, 'id');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
答案 1 :(得分:2)
您可以获得扁平的食谱集合,连接响应,然后按ID键入:
var result = _.chain(resp)
.flatMap('recipes')
.concat(resp)
.keyBy('id')
.value()
flatMap调用将从响应中获取所有配方并压平数组,以便我们留下这个:
[
{ "id": 4036 },
{ "id": 4041 },
{ "id": 4052 },
{ "id": 4053 }
]
然后使用concat将响应附加到此数组,然后我们将:
[
{ "id": 4036 },
{ "id": 4041 },
{ "id": 4052 },
{ "id": 4053 },
{ "id": "1", recipes: ... },
{ "id": "2", recipes: ... }
]
最后,我们使用keyBy来获取所需的结构。
var resp = [
{
"id": "1",
"recipes": [
{
"id": 4036
},
{
"id": 4041
}
]
},
{
"id": "2",
"recipes": [
{
"id": 4052
},
{
"id": 4053
}
]
}
]
var result = _.chain(resp)
.flatMap('recipes')
.concat(resp)
.keyBy('id')
.value()
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<p>
<pre id="result"></pre>
</p>
答案 2 :(得分:2)
您可以使用_.keyBy
和_.mapValues
_.chain(resp)
.keyBy('id')
.mapValues(function(item) {
item.recipes = _.keyBy(item.recipes, 'id');
return item;
})
.value();