Search code examples
javascriptgrouping

Javascript Grouping by object property, when property is an array


I currently have an array of items that looks a bit like this: I want to group the items by category lookup, with the slight problem that category lookup is potentially an array, such that Parent Item 2 would be listed twice (once in My Cat) and once in something else) I tried using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/groupBy but it doesn't seem to be able to handle this?

     [
           {
                "tool_id": "4-19de-454673d9-9ef5-4545",
                "somekey" : "Parent Item 2"
                "categoryLookup": [
                    {
                        "category_name": "New Item",
                    }
                ]
            },
            {
                "tool_id": "be7ea707-19de-43d9-9ef1-d4a3ff79f77a",
                "somekey" : "Parent Item"
                "categoryLookup": [
                    {
                        "category_name": "My Cat",
                    },
                    {
                        "category_name": "Something Else",
                    }
                ]
            }
     ]

The final result would look something like:

    [
       {
           New Item: [
              {...contains 4-19de-454673d9-9ef5-4545 }
           ],
           My Cat: [
              {...contains be7ea707-19de-43d9-9ef1-d4a3ff79f77a}
           ],
           Something Else: [
              {... contain be7ea707-19de-43d9-9ef1-d4a3ff79f77a} 
           ]
        }
    ]

Solution

  • You can iterate over the original array and create the final one:

    var data = [{
        "tool_id": "4-19de-454673d9-9ef5-4545",
        "somekey": "Parent Item 2",
        "categoryLookup": [{
          "category_name": "New Item",
        }]
      },
      {
        "tool_id": "be7ea707-19de-43d9-9ef1-d4a3ff79f77a",
        "somekey": "Parent Item",
        "categoryLookup": [{
            "category_name": "My Cat",
          },
          {
            "category_name": "Something Else",
          }
        ]
      }
    ];
    
    function groupByCategory(data) {
      const res = {};
    
      data.forEach(item => {
        item.categoryLookup.forEach(category => {
          const name = category.category_name;
          res[name] ??= [];
          res[name].push({
            item: item.tool_id //or all the properties you want
          });
        });
      });
      return res;
    }
    
    console.log( groupByCategory(data) );