Search code examples
javascriptlistobjectlodash

Self merging an object - lodash


I have one object:

obj1 = [{
           "accId": 23,
           "sName" : "qw" 
        }, 
        { 
           "accId": 23,
           "sName": "as" 
        },
        {
           "accId":24,
           "sName": "we"
        }
] 

I want to use lodash to self merge this list of object into:

result = [{
             "accId": 23,
             "sName" : ["qw","as"]

          },
          {
           "accId":24,
           "sName": ["we"]
          }
]

I tried using pure javascript with for loops but it seems very inefficient. I also tried some lodash functions but could not find a perfect fit. I have also thought of the idea of splitting the list of objects into separate lists with one object per list and merging using _.merge(). But I don't know if there is a way to split the list of objects.


Solution

  • With lodash you can use _.flow() to generate a function that starts by grouping items with the same accId, and then maps each group and generate a new object, with the collected sName values of the group:

    const { flow, partialRight: pr, groupBy, map, head } = _
    
    const fn = flow(
      pr(groupBy, 'accId'),
      pr(map, vs => ({ ...head(vs), sName: map(vs, 'sName')}))
    )
    
    const array = [{"accId":23,"sName":"qw"},{"accId":23,"sName":"as"},{"accId":24,"sName":"we"}]
    
    const result = fn(array)
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    And the same idea with Lodash/fp:

    const { flow, groupBy, map, head } = _
    
    const fn = flow(
      groupBy('accId'),
      map(vs => ({ ...head(vs), sName: map('sName', vs)}))
    )
    
    const array = [{"accId":23,"sName":"qw"},{"accId":23,"sName":"as"},{"accId":24,"sName":"we"}]
    
    const result = fn(array)
    
    console.log(result);
    <script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>