Search code examples
javascriptdictionarygroupinglodash

lodash filter object array and group by to create a new array


Below is the main array, i want to group by dept.name and remove all other fields except "e-depid" to single array

Main array

  [
    {
      "id": "67",
      "empid": 5,
      "e-depid": "ab",
      "dept": { "name": "Prod" }
    },
    {
      "id": "67",
      "empid": 7,
      "e-depid": "ac",
      "dept": { "name": "Prod" }
    },
    {
      "id": "67",
      "empid": 5,
      "e-depid": "ad",
      "dept": { "name": "mkt" }
    }
  ]

Result array

  [
    {
      "Prod": { "e-depid": ["ab", "ac"] },
      "mkt": { "e-depid": ["ad"] }
    }
  ]

Solution

  • Can be quite clean with a simple Array.prototype.reduce() call.

    const
      input = [{ "id": "67", "empid": 5, "e-depid": "ab", "dept": { "name": "Prod" } }, { "id": "67", "empid": 7, "e-depid": "ac", "dept": { "name": "Prod" } }, { "id": "67", "empid": 5, "e-depid": "ad", "dept": { "name": "mkt" } }],
    
      result = input.reduce((a, { dept: { name }, 'e-depid': e }) => (
        (a[name] || (a[name] = { 'e-depid': [] }))['e-depid'].push(e), a
      ), {});
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    Original answer using logical nullish assignment (??=)

    const
      input = [{ "id": "67", "empid": 5, "e-depid": "ab", "dept": { "name": "Prod" } }, { "id": "67", "empid": 7, "e-depid": "ac", "dept": { "name": "Prod" } }, { "id": "67", "empid": 5, "e-depid": "ad", "dept": { "name": "mkt" } }],
    
      result = input.reduce((a, { dept: { name }, 'e-depid': e }) => (
        (a[name] ??= { 'e-depid': [] })['e-depid'].push(e), a
      ), {})
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }