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

前端 未结 6 1830
谎友^
谎友^ 2020-12-08 07:34

I have two collections, and the objects have a common key \"userId\". As below:

var _= require(\'lodash\');

var a = [
  { userId:\"p1\", item:1},
  { userId         


        
6条回答
  •  遥遥无期
    2020-12-08 07:38

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

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

提交回复
热议问题