简体   繁体   English

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

[英]How to use Lodash to merge two collections based on a key?

I have two collections, and the objects have a common key "userId".我有两个集合,对象有一个公共键“userId”。 As below:如下:

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}
];

I want to merge them based on "userId" to produce:我想根据“userId”合并它们以产生:

[ { userId: 'p1', item: 1, profile: 1 },
  { userId: 'p2', item: 2, profile:2 },
  { userId: 'p3', item: 4 } ]

I have these so far:到目前为止,我有这些:

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

Which result in:结果是:

[ { userId: 'p1', item: 1 },
  { userId: 'p2', item: 2 },
  { userId: 'p3', item: 4 },
  { userId: 'p1', profile: 1 },
  { userId: 'p2', profile: 2 } ]

How can I merge them now?我现在如何合并它们?

I tried _.keyBy but it results in:我试过 _.keyBy 但结果是:

{ p1: { userId: 'p1', profile: 1 },
  p2: { userId: 'p2', profile: 2 },
  p3: { userId: 'p3', item: 4 } }

which is wrong.这是错误的。

What's the last step I should do?我应该做的最后一步是什么?

Second highest voted answer doesn't do proper merge.投票第二高的答案没有正确合并。 If second array contains an unique property, it is not taken into account.如果第二个数组包含唯一属性,则不考虑。

This approach does a proper merge.这种方法进行了适当的合并。

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:"p4", profile:4} ]; var merged = _.merge(_.keyBy(a, 'userId'), _.keyBy(b, 'userId')); var values = _.values(merged); console.log(values);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

ES6+ ES6+

 // from https://stackoverflow.com/a/34749873/80766 const mergeDeep = (target, ...sources) => { if (!sources.length) return target; const source = sources.shift(); if (target instanceof Object && source instanceof Object) { for (const key in source) { if (source[key] instanceof Object) { if (!target[key]) Object.assign(target, { [key]: {} }); mergeDeep(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return mergeDeep(target, ...sources); } const a = [ { userId:"p1", item:1}, { userId:"p2", item:2}, { userId:"p3", item:4} ]; const b = [ { userId:"p1", profile:1}, { userId:"p2", profile:2}, { userId:"p4", profile:4} ]; const aKeyed = a.reduce((acc, cur) => ({ ...acc, [cur.userId]: cur }), {}); const bKeyed = b.reduce((acc, cur) => ({ ...acc, [cur.userId]: cur }), {}); const merged = mergeDeep(aKeyed, bKeyed); const values = Object.values(merged); console.log(values);

You can use _.map() , _.assign() and _.find() .您可以使用_.map()_.assign()_.find()

// 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}));
});

Fiddle Demo小提琴演示

 var a = [{ userId: "p1", item: 1 }, { userId: "p2", item: 2 }, { userId: "p3", item: 4 }]; var b = [{ userId: "p1", profile: 1 }, { userId: "p2", profile: 2 }]; var arrResult = _.map(a, function(obj) { return _.assign(obj, _.find(b, { userId: obj.userId })); }); console.log(arrResult); document.getElementById('result').innerHTML = JSON.stringify(arrResult, 0, 4);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.1.0/lodash.min.js"></script> <pre id="result"></pre>

Lodash has a merge method that works on objects (objects with the same key are merged). Lodash 有一个适用于对象的merge方法(合并具有相同键的对象)。 In this demo, the arrays a and b are first converted into objects (where userId is the key), then merged, and the result converted back to an array ( _.values ) (getting rid of the keys).在这个演示中,数组ab首先转换为对象(其中userId是键),然后合并,并将结果转换回数组( _.values )(去掉键)。 _.flatten is then necessary because _.values adds an extra level of array. _.flatten然后是必要的,因为_.values增加了一个额外的数组级别。

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

Just for completeness: A proposal without any library.只是为了完整性:一个没有任何图书馆的提案。

 function merge(a, b, key) { function x(a) { a.forEach(function (b) { if (!(b[key] in obj)) { obj[b[key]] = obj[b[key]] || {}; array.push(obj[b[key]]); } Object.keys(b).forEach(function (k) { obj[b[key]][k] = b[k]; }); }); } var array = [], obj = {}; x(a); x(b); return array; } var a = [ { userId: "p1", item: 1 }, { userId: "p2", item: 2 }, { userId: "p3", item: 4 } ], b = [ { userId: "p1", profile: 1 }, { userId: "p2", profile: 2 } ], c = merge(a, b, 'userId'); document.write('<pre>' + JSON.stringify(c, 0, 4) + '</pre>');

ES6+ version without lodash.没有 lodash 的 ES6+ 版本。

 const array1 = [{ userId: "p1", item: 1 }, { userId: "p2", item: 2 },{ userId: "p3", item: 4 }]; const array2 = [{ userId: "p1", profile: 1 }, { userId: "p2", profile: 2 }]; const result = array1.map(a => ({ ...a, ...array2.find(b => b.userId === a.userId) // _.find(array2, 'skuId') <-- or with lodash })); document.write('<pre>' + JSON.stringify(result, 0, 2) + '</pre>');

Try this demo试试这个演示

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Lodash - 如何根据键合并两个对象数组? - Lodash - How to merge two arrays of objects based on key? 如何使用lodash通过键合并两个大小不同的对象数组 - how to merge two object arrays of different size by key using lodash 使用 Lodash 根据 keyValue 合并两个对象 - Merge the two object based on keyValue using Lodash 如何根据文档中的参考ID合并并观察Firestore中的两个集合? - How to merge and observe two collections in Firestore based on reference ID in documents? 如何使用lodash将两个数组合并为一个对象 - how to merge two arrays into a object using lodash 在lodash中合并两个对象 - merge two objects in lodash LoDash-如何通过公用密钥将一个集合值推入另一个 - LoDash - How to push one collections values into another via common key 如果我使用 lodash 的 union 根据一组布尔设置来合并对象,那么如何优雅地编写它? - If I use lodash's union to merge objects based on a set of boolean settings, how would one write it elegantly? 如何使用基于两个collections文件的云function触发器 - How to use cloud function trigger based on two collections documents 如何在mongodb中合并两个collections,聚合mongodb - How to merge two collections in mongodb, aggregate mongodb
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM