使用Java中的Lodash或下划线在具有多个列的GroupBy

时间:2019-07-27 20:59:58

标签: javascript json underscore.js lodash

在转换JSON结构时遇到问题。我的JSON结构如下。

const member = [{
    memberId: 4,
    memberName: 'ABC',
    age: 22,
    eventId: 5,
    eventName: 'Dance'
  },
  {
    memberId: 4,
    memberName: 'ABC',
    age: 22,
    eventId: 6,
    eventName: 'Music'
  },
  {
    memberId: 4,
    memberName: 'ABC',
    age: 22,
    eventId: 7,
    eventName: 'FootBall'
  },
  {
    memberId: 5,
    memberName: 'PQR',
    age: 24,
    eventId: 6,
    eventName: 'Music'
  },
  {
    memberId: 5,
    memberName: 'PQR',
    age: 24,
    eventId: 5,
    eventName: 'Dance'
  },
]

在这里,我有两个具有关联事件的成员。我想按以下方式转换JSON。

const member = [
  {
    memberId: 4,
    memberName: 'ABC',
    age: 22,
    events: [
      {
        id: 5,
        name: 'Dance'
      },
      {
        id: 6,
        name: 'Music'
      },
      {
        id: 7,
        name: 'FootBall'
      }
    ]
  },
  {
    memberId: 5,
    memberName: 'PQR',
    age: 24,
    events: [
      {
        id: 6,
        name: 'Music'
      },
      {
        id: 5,
        name: 'Dance'
      }
    ]
  }
]

我尝试使用以下代码创建结构,但未提供所需的输出。它只是创建两个键值对。

var result = _.chain(member)
            .groupBy("memberId")
            .pairs()
            .map(function(currentItem) {
                return _.object(_.zip(["memberId", "events"], currentItem));
            })
            .value();

我不知道如何在层次结构中添加其他JSON值。

1 个答案:

答案 0 :(得分:1)

将项目分组后,将它们映射。取每个组的第一项,然后删除事件属性,并将其传播。要获取事件数据,请映射组的项目并仅获取相关事件属性:

const member = [{"memberId":4,"memberName":"ABC","age":22,"eventId":5,"eventName":"Dance"},{"memberId":4,"memberName":"ABC","age":22,"eventId":6,"eventName":"Music"},{"memberId":4,"memberName":"ABC","age":22,"eventId":7,"eventName":"FootBall"},{"memberId":5,"memberName":"PQR","age":24,"eventId":6,"eventName":"Music"},{"memberId":5,"memberName":"PQR","age":24,"eventId":5,"eventName":"Dance"}]

const result = _(member)
  .groupBy('memberId')
  .map(group => ({
    ..._.omit(_.head(group), ['eventId', 'eventName']),
    events: _.map(group, o => ({ id: o.eventId, name: o.eventName }))
  }))
  .value();
  
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

和使用下划线的相同解决方案:

const member = [{"memberId":4,"memberName":"ABC","age":22,"eventId":5,"eventName":"Dance"},{"memberId":4,"memberName":"ABC","age":22,"eventId":6,"eventName":"Music"},{"memberId":4,"memberName":"ABC","age":22,"eventId":7,"eventName":"FootBall"},{"memberId":5,"memberName":"PQR","age":24,"eventId":6,"eventName":"Music"},{"memberId":5,"memberName":"PQR","age":24,"eventId":5,"eventName":"Dance"}]

const result = _.chain(member) // <- change for underscore 
  .groupBy('memberId')
  .map(group => ({
    ..._.omit(_.head(group), ['eventId', 'eventName']),
    events: _.map(group, o => ({ id: o.eventId, name: o.eventName }))
  }))
  .value();
  
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>