我有两个数组:
var a = [
{aId: 1, name: "a1"},
{aId: 2, name: "a2"}
];
var b = [
{parentId: 1, description: "b1"},
{parentId: 1, description: "b2"},
{parentId: 2, description: "b3"}
];
我想基于parentid === aid;
合并这些阵列我做到了:
var c = _.map(a, function(obj) {
return _.assign(obj, _.find(b, {parentId: obj.aId}));
})
jsfiddle
这可以按预期工作,但是我需要它处理重复项 - 当找到匹配项时,它会正确合并,但是我需要将其推入新属性,而不是合并。
。我得到的:
[
{aId: 1, name: "a1", description: "b1"},
{aId: 2, name: "a2", description: "b3"}
]
我想要的:
[
{
aId: 1,
name: "a1",
b: [
{parentId: 1, description: "b1"},
{parentId: 1, description: "b2"}
]
},
{
aId: 2,
name: "a2",
b: [
{parentId: 2, description: "b1"}
]
}
]
当然可以省略公共属性;
编辑
虽然此答案非常有帮助,并且在一定程度上满足了原始问题,但有关评论中突变的讨论可能会导致意外行为,例如使用Redux或其他依赖不可变状态的库。p>原始答案使用导致突变的_.assign
。下面使用ES6扩展操作员将新对象返回新数组。
const a = [{aId: 1, name: "a1"}, {aId: 2, name: "a2"}];
const b = [{parentId: 1, description: "b1"}, {parentId: 1, description: "b2"}, {parentId: 2, description: "b3"}];
const c = _.map(a, (obj) =>
({ ...obj, ...{ b: _.filter(b, {parentId: obj.aId}) }});
console.log('mimick original', c);
原始答案:
您的代码几乎完成了;在_.Assign()中,您可以通过属性b
传递一个对象,等于_.filter()的结果,而不是_.find():
{
b: _.filter(b, {parentId: obj.aId})
}
请注意,_.find()返回匹配的元素,else undefined and _.filter()返回新的过滤阵列。
代码:
var a = [{aId: 1, name: "a1"}, {aId: 2, name: "a2"}],
b = [{parentId: 1, description: "b1"}, {parentId: 1, description: "b2"}, {parentId: 2, description: "b3"}];
_.map(a, function(obj) {
return _.assign(obj, {
b: _.filter(b, {parentId: obj.aId})
});
});
console.log(a);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>