Javascript Lodash-根据条件合并两个数组的对象
我有两个对象数组Javascript Lodash-根据条件合并两个数组的对象,javascript,arrays,collections,lodash,Javascript,Arrays,Collections,Lodash,我有两个对象数组 arr1 = [ { myName: 'Adam', mySkill: 'CSS', }, { myName: 'Mutalib', mySkill: 'JavaScript', }, ]; arr2 = [ { myName: 'Adam', myWeight: '112', }, { myName: 'Habib', myWeight: '221', }, ]; 我想要的结果
arr1 = [
{
myName: 'Adam',
mySkill: 'CSS',
},
{
myName: 'Mutalib',
mySkill: 'JavaScript',
},
];
arr2 = [
{
myName: 'Adam',
myWeight: '112',
},
{
myName: 'Habib',
myWeight: '221',
},
];
我想要的结果是一个数组,它包含第一个数组的对象,这些对象在第二个数组中具有匹配的属性“myName”,并具有相应的第二个数组对象的附加属性
result = [
{
myName = 'Adam'
mySkill = 'CSS'
myWeight = '112'
}
];
使用Array.prototype.forEach
和Object.assign
函数的替代本机JS解决方案:
var arr1=[
{myName:'Adam',mySkill:'CSS'},{myName:'Mutalib',mySkill:'JavaScript'},
],
arr2=[
{myName:'Adam',myWeight:'112'},{myName:'Habib',myWeight:'221'}
],
结果=[];
arr1.forEach(函数(o){
arr2.forEach(功能(c){
if(o.myName==c.myName)result.push(Object.assign({},o,c));
})
});
控制台日志(结果)
只有在myName
是公共的情况下,才可以使用哈希表推送对象
var arr1=[{myName:'Adam',mySkill:'CSS'},{myName:'Mutalib',mySkill:'JavaScript'}],
arr2=[{myName:'Adam',myWeight:'112'},{myName:'Habib',myWeight:'221'}],
hash=Object.create(null),
结果=[];
arr1.forEach(函数(a){
hash[a.myName]={myName:a.myName,mySkill:a.mySkill};
});
arr2.forEach(函数(a){
if(散列[a.myName]){
hash[a.myName].myWeight=a.myWeight;
push(hash[a.myName]);
}
});
控制台日志(结果)代码>
。作为控制台包装{max height:100%!important;top:0;}
您还可以在Map对象的帮助下执行以下操作
函数mergeObjectsIfExists(p,a,b){
var m=a.reduce((m,o)=>m.set(o[p],o),newmap());
返回b.reduce((r,o)=>m.has(o[p])?(r.push(m.set(o[p],Object.assign(m.get(o[p]),o)).get(o[p])),r)
:r,[]);
}
var arr1=[{myName:'Adam',mySkill:'CSS'},{myName:'Mutalib',mySkill:'JavaScript'},{myName:'Jessuro',mySkill:'Haskell'}],
arr2=[{myName:'Adam',myWeight:'112'},{myName:'Habib',myWeight:'221'},{myName:'Jessuro',myIQ:'150'}],
结果=mergeObjectsIfExists(“myName”,arr1,arr2);
控制台日志(结果)
通过myName
在数组(arr1
和arr2
)下方执行的解决方案,使用删除仅包含一个项目的所有组,最后使用生成的数组
var result = _(arr1)
.concat(arr2)
.groupBy('myName')
.reject({ length: 1 })
.map(_.spread(_.merge))
.value();
var arr1=[
{
我的名字:“亚当”,
mySkill:'CSS',
},
{
我的名字:“Mutalib”,
mySkill:'JavaScript',
}
];
var arr2=[
{
我的名字:“亚当”,
我的体重:“112”,
},
{
我的名字:“哈比卜”,
我的体重:“221”,
}
];
var结果=U1(arr1)
.concat(arr2)
.groupBy('myName'))
.reject({length:1})
.map(u.spread(u.merge))
.value();
控制台日志(结果)代码>
如果使用lodash/fp
可以组合函数以实现所需的功能。假设myName
是您的PK(或合并枢轴),您可以执行以下操作:
const mergeByName = compose(values, spread(merge), map(keyBy('myName')));
> mergeByName([arr1, arr2])
[ { myName: 'Adam', mySkill: 'CSS', myWeight: '112' },
{ myName: 'Mutalib', mySkill: 'JavaScript' },
{ myName: 'Habib', myWeight: '221' } ]
是的,我最初的解决方案看起来有点像这样。我想知道是否有一个简单的方法来处理lodash,但我想没有。这当然有效,但它是一个低效的O(n^2)解决方案。谢谢。我不确定这是否比叠瓦foreach循环更具可读性,谢谢。在这种情况下,本机Js解决方案似乎更具吸引力simple@MisterFresh查看我的替代解决方案。已接受。简化了一点:var result=u.intersectionWith(arr1,arr2,(x,y)=>x.myName==y.myName&&&uu.assign(x,y))。。我认为IntersectionWith中的比较器只返回一个布尔值,但显然它是一个映射function@MisterFresh它更可能是一个forEach
而不是map
。我只是用短路操作作为利用任务的一种方式。