Search code examples
javascriptlodash

Group Array of Objects of same level


I have an array which has different level of approvers. I need to combine the object of similar level and group them with the Name+counter.

"APPROVERS": [
        {
            "LEVEL": "L5",
            "EMAIL": "[email protected]",
            "FULLNAME": "FNAME",
            "POSITION": "FPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L4",
            "EMAIL": "[email protected]",
            "FULLNAME": "JNAME",
            "POSITION": "JPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L5",
            "EMAIL": "[email protected]",
            "FULLNAME": "LNAME",
            "POSITION": "GPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        },
        {
            "LEVEL": "L5",
            "EMAIL": "[email protected]",
            "FULLNAME": "TNAME",
            "POSITION": "CPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        }  
    ]

I need to combine the objects of same level into one and provide the unique name.

 "APPROVERS": [
        {
            "LEVEL": "L5",
            "EMAIL1": "[email protected]",
            "FULLNAME1": "FNAME",
            "POSITION1": "FPOS",
            "SLA1": "48",
            "STATUS1": "INITIAL",
            "EMAIL2": "[email protected]",
            "FULLNAME2": "LNAME",
            "POSITION2": "GPOS",
            "SLA2": "48",
            "STATUS2": "INITIAL",
            "EMAIL3": "[email protected]",
            "FULLNAME3": "TNAME",
            "POSITION3": "CPOS",
            "SLA3": "48",
            "STATUS3": "INITIAL"
        },
        {
            "LEVEL": "L4",
            "EMAIL": "[email protected]",
            "FULLNAME": "JNAME",
            "POSITION": "JPOS",
            "SLA": "48",
            "STATUS": "INITIAL"
        } 
    ]

I tried only to combine EMAIL by looping the array but not able to achieve the result.Kindly suggest.

var result = [];
    var i=0
    APPROVERS.forEach(function(obj) {
      var id = obj.LEVEL
      if(!this[id]) result.push(this[id] = obj);
      else this[id].EMAIL += obj.EMAIL+i;
      i++;
    }, Object.create(null));

    console.log(result)

Solution

  • By putting the tag lodash I guess you don't mind using it. I'm not sure you understand it, but I've tried my best to balance between succinctness and readability.

    function groupByLevel(approvers) {
    
      const group = _.groupBy(approvers, 'LEVEL');
      // console.log(group); // try logging to see what we have
    
      return Object.entries(group).map( ([LEVEL, array]) => {
    
        return array.reduce((acc, cur, idx) => ({
          ...acc,
          ['EMAIL'    + (idx + 1)]: cur.EMAIL    ,
          ['FULLNAME' + (idx + 1)]: cur.FULLNAME ,
          ['POSITION' + (idx + 1)]: cur.POSITION ,
          ['SLA'      + (idx + 1)]: cur.SLA      ,
          ['STATUS'   + (idx + 1)]: cur.STATUS   ,
    
        }), { LEVEL });
      })
    }
    
    
    
    
    
    
    
    
    
    
    
    
    var APPROVERS = [
      {
        LEVEL: 'L5',
        EMAIL: '[email protected]',
        FULLNAME: 'FNAME',
        POSITION: 'FPOS',
        SLA: '48',
        STATUS: 'INITIAL'
      },
      {
        LEVEL: 'L4',
        EMAIL: '[email protected]',
        FULLNAME: 'JNAME',
        POSITION: 'JPOS',
        SLA: '48',
        STATUS: 'INITIAL'
      },
      {
        LEVEL: 'L5',
        EMAIL: '[email protected]',
        FULLNAME: 'LNAME',
        POSITION: 'GPOS',
        SLA: '48',
        STATUS: 'INITIAL'
      },
      {
        LEVEL: 'L5',
        EMAIL: '[email protected]',
        FULLNAME: 'TNAME',
        POSITION: 'CPOS',
        SLA: '48',
        STATUS: 'INITIAL'
      }
    ]
    console.log(groupByLevel(APPROVERS))
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>