Javascript 如何使用Lodash基于一个键合并两个集合?

Javascript 如何使用Lodash基于一个键合并两个集合?,javascript,collections,merge,lodash,Javascript,Collections,Merge,Lodash,我有两个集合,对象有一个公共键“userId”。详情如下: var _= require('lodash'); var a = [ { userId:"p1", item:1}, { userId:"p2", item:2}, { userId:"p3", item:4} ]; var b = [ { userId:"p1", profile:1}, { userId:"p2", profile:2} ]; 我想根据“userId”合并它们以生成: [ { userId

我有两个集合,对象有一个公共键“userId”。详情如下:

var _= require('lodash');

var a = [
  { userId:"p1", item:1},
  { userId:"p2", item:2},
  { userId:"p3", item:4}
];

var b = [
  { userId:"p1", profile:1},
  { userId:"p2", profile:2}
];
我想根据“userId”合并它们以生成:

[ { userId: 'p1', item: 1, profile: 1 },
  { userId: 'p2', item: 2, profile:2 },
  { userId: 'p3', item: 4 } ]
到目前为止,我有以下几点:

var u = _.uniq(_.union(a, b), false, _.property('userId'));
这导致:

[ { userId: 'p1', item: 1 },
  { userId: 'p2', item: 2 },
  { userId: 'p3', item: 4 },
  { userId: 'p1', profile: 1 },
  { userId: 'p2', profile: 2 } ]
我现在如何合并它们

我尝试了u.keyBy,但结果是:

{ p1: { userId: 'p1', profile: 1 },
  p2: { userId: 'p2', profile: 2 },
  p3: { userId: 'p3', item: 4 } }
这是错误的

我应该做的最后一步是什么

您可以使用,和

var a=[{
用户标识:“p1”,
项目:1
}, {
用户标识:“p2”,
项目:2
}, {
用户标识:“p3”,
项目:4
}];
变量b=[{
用户标识:“p1”,
简介:1
}, {
用户标识:“p2”,
个人资料:2
}];
var arrResult=u2;.map(a,函数(obj){
返回赋值(obj,find,b{
userId:obj.userId
}));
});
控制台日志(arresult);
document.getElementById('result').innerHTML=JSON.stringify(arresult,0,4)

试试这个


只是为了完整:一个没有任何库的提案

函数合并(a、b、键){
功能x(a){
a、 forEach(函数(b){
如果(!(obj中的b[键]){
obj[b[key]]=obj[b[key]]| |{};
array.push(obj[b[key]]);
}
对象。键(b)。forEach(函数(k){
obj[b[key][k]=b[k];
});
});
}
变量数组=[],
obj={};
x(a);
x(b);
返回数组;
}
变量a=[
{userId:“p1”,项目:1},
{userId:“p2”,项目:2},
{用户标识:“p3”,项目:4}
],
b=[
{userId:“p1”,配置文件:1},
{userId:“p2”,配置文件:2}
],
c=合并(a,b,'userId');

document.write(''+JSON.stringify(c,0,4)+'')
Lodash有一个
merge
方法,可用于对象(合并具有相同键的对象)。在本演示中,数组
a
b
首先转换为对象(其中
userId
是键),然后合并,结果转换回数组(
.values
)(去掉键)<因为
..values
添加了一个额外的数组级别,所以有必要使用code>.\u0.flatte


不含lodash的ES6+版本

const array1=[{userId:“p1”,项:1},{userId:“p2”,项:2},{userId:“p3”,项:4}];
const array2=[{userId:“p1”,profile:1},{userId:“p2”,profile:2}];
const result=array1.map(a=>({
A.

…array2.find(b=>b.userId==a.userId)/\uy2.find(array2,'skuId')投票数第二高的答案未正确合并。如果第二个数组包含唯一属性,则不考虑该属性

这种方法进行适当的合并

洛达斯
var a=[
{userId:“p1”,项目:1},
{userId:“p2”,项目:2},
{用户标识:“p3”,项目:4}
];
变量b=[
{userId:“p1”,配置文件:1},
{userId:“p2”,配置文件:2},
{userId:“p4”,配置文件:4}
];
var merged=u0.merge(0.keyBy(a,'userId'),0.keyBy(b,'userId'));
var值=u0.values(合并);
console.log(值);

只是一个想法,如果第二个列表包含唯一的userId,则不会添加到最终列表中。我怀疑这是OP不想要的行为。这些函数现在在最新版本的JS中可用。
a.map(obj=>Object.assign(obj,b.find(user=>obj.userId==user.userId)))
这可能不适合所有情况,如果
userId
字段不是每个集合唯一的,则数据将压缩到单个对象中。
// Iterate over first array of objects
_.map(a, function(obj) {

    // add the properties from second array matching the userID
    // to the object from first array and return the updated object
    return _.assign(obj, _.find(b, {userId: obj.userId}));
});
var a = [{
    userId: "p1",
    item: 1
}, {
    userId: "p2",
    item: 2
}, {
    userId: "p3",
    item: 4
}];

var b = [{
    userId: "p1",
    profile: 1
}, {
    userId: "p2",
    profile: 2
}];

a.forEach(function (aitem) {
    b.forEach(function (bitem) {
        if(aitem.userId === bitem.userId) {
            _.assign(aitem, bitem);
        }
    });
});

console.log(a);
var u= _({}) // Start with an empty object
  .merge(
    _(a).groupBy("userId").value(),
    _(b).groupBy("userId").value()
  )
  .values()
  .flatten()
  .value();