Search code examples
javascriptarraysjsonlodash

Javascript group objects by value


Firstly I need to group an array of object with respect to policy attribute's value. Then I need to group action and company fields. I tried to use lodash but could not get to the nested arrays.

From this =>

[
    {
        "action": "VIEW",
        "policy": "FORM"
    },
    {
        "action": "CREATE",
        "policy": "USER"
    },
    {
        "action": "VIEW",
        "policy": "USER"
    },
    {
        "company": "Microsoft",
        "policy": "FORM"
    },
    {
        "company": "Facebook",
        "policy": "USER"
    },
    {
        "company": "Twitter",
        "policy": "USER"
    }
]

to this =>

{
    "FORM": {
            "action": ["VIEW"],
            "company": ["Microsoft"]
        },
    "USER": {
            "action": ["CREATE", "VIEW"],
            "company": ["Facebook", "Twitter"]
        }
}

Thanks a lot


Solution

  • You can do this using a simple for...of loop and some destructuring:

    const data = [ { action: 'VIEW', policy: 'FORM', }, { action: 'CREATE', policy: 'USER', }, { action: 'VIEW', policy: 'USER', }, { company: 'Microsoft', policy: 'FORM', }, { company: 'Facebook', policy: 'USER', }, { company: 'Twitter', policy: 'USER', }, ];
    let result = {};
    
    for (const { action, policy, company } of data) {
      result[policy] = result[policy] ?? { action: [], company: [] };
      if (action) result[policy].action.push(action);
      if (company) result[policy].company.push(company);
    }
    
    console.log(result);

    You could also do this using array#reduce instead of a for loop:

    const data = [ { action: 'VIEW', policy: 'FORM' }, { action: 'CREATE', policy: 'USER' }, { action: 'VIEW', policy: 'USER' }, { company: 'Microsoft', policy: 'FORM' }, { company: 'Facebook', policy: 'USER' }, { company: 'Twitter', policy: 'USER' }, ];
    
    const result = data.reduce((result, { action, company, policy }) => {
      result[policy] = result[policy] ?? { action: [], company: [] };
      action && result[policy].action.push(action);
      company && result[policy].company.push(company);
      return result;
    }, {});
    
    console.log(result);