首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Lodash根据一个键合并两个集合?

如何使用Lodash根据一个键合并两个集合?
EN

Stack Overflow用户
提问于 2016-01-30 02:55:04
回答 5查看 58.9K关注 0票数 32

我有两个集合,对象都有一个公共键"userId“。如下所示:

代码语言:javascript
运行
复制
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“将它们合并,以生成:

代码语言:javascript
运行
复制
[ { userId: 'p1', item: 1, profile: 1 },
  { userId: 'p2', item: 2, profile:2 },
  { userId: 'p3', item: 4 } ]

到目前为止,我有以下几点:

代码语言:javascript
运行
复制
var u = _.uniq(_.union(a, b), false, _.property('userId'));

这会导致:

代码语言:javascript
运行
复制
[ { userId: 'p1', item: 1 },
  { userId: 'p2', item: 2 },
  { userId: 'p3', item: 4 },
  { userId: 'p1', profile: 1 },
  { userId: 'p2', profile: 2 } ]

现在如何合并它们?

我尝试过_.keyBy,但结果是:

代码语言:javascript
运行
复制
{ p1: { userId: 'p1', profile: 1 },
  p2: { userId: 'p2', profile: 2 },
  p3: { userId: 'p3', item: 4 } }

这是错误的。

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

EN

回答 5

Stack Overflow用户

发布于 2018-08-21 08:30:11

得票率第二高的答案没有进行适当的合并。如果第二个数组包含唯一属性,则不会将其考虑在内。

这种方法进行了适当的合并。

Lodash

代码语言:javascript
运行
复制
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);
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

ES6+

代码语言:javascript
运行
复制
// 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);

票数 47
EN

Stack Overflow用户

发布于 2017-01-17 22:52:47

Lodash有一个在对象上工作的merge方法(具有相同键的对象被合并)。在本演示中,数组ab首先转换为对象(其中userId是键),然后合并,并将结果转换回数组(_.values) (去掉键)。因此,_.flatten是必需的,因为_.values添加了额外的数组级别。

代码语言:javascript
运行
复制
var u= _({}) // Start with an empty object
  .merge(
    _(a).groupBy("userId").value(),
    _(b).groupBy("userId").value()
  )
  .values()
  .flatten()
  .value();
票数 7
EN

Stack Overflow用户

发布于 2016-01-30 06:10:15

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

代码语言:javascript
运行
复制
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>');

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35091975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档