Group by an item in a nested array using laravel collection

Viewed 223

I have an array that has the variable name $array and it is as follows:

$array = [
    "data"=> [
        [
            "company"=>[
                "id"=> 1,
                "name"=> "company1"
            ],
            "reports"=> [
                "active_reports"=> 3,
                "completed_reports"=> 2
            ]
        ],
        [
            "company"=>[
                "id"=> 2,
                "name"=> "company2"
            ],
            "reports"=> [
                "active_reports"=> 6,
                "completed_reports"=> 1
            ]
        ],
        [
            "company"=>[
                "id"=> 2,
                "name"=> "company2"
            ],
            "reports"=> [
                "active_reports"=> 7,
                "completed_reports"=> 5
            ]
        ]
    ]
];

So, I want to group this array by the company id. The id can be found in the nested array with key company

My expected result is below:

{
  "1": [
    {
      "company": {
        "id": 1,
        "name": "company1"
      },
      "reports": {
        "active_reports": 3,
        "completed_reports": 2
      }
    }
  ],
  "2": [
    {
      "company": {
        "id": 2,
        "name": "company2"
      },
      "reports": {
        "active_reports": 6,
        "completed_reports": 1
      }
    },
    {
      "company": {
        "id": 2,
        "name": "company2"
      },
      "reports": {
        "active_reports": 7,
        "completed_reports": 5
      }
    }
  ]
}

So, I tried the following logic:

foreach ($array['data'] as $data) {

   $reportsData = collect($data)->groupBy($data['company']['id']);

   Log::info($reportsData);
}

But this is the result I'm getting after trying the above logic:

[
  {
    "": [
      {
        "id": 1,
        "name": "company1"
      },
      {
        "active_reports": 3,
        "completed_reports": 2
      }
    ]
  },
  {
    "": [
      {
        "id": 2,
        "name": "company2"
      },
      {
        "active_reports": 6,
        "completed_reports": 1
      }
    ]
  },
  {
    "": [
      {
        "id": 2,
        "name": "company2"
      },
      {
        "active_reports": 7,
        "completed_reports": 5
      }
    ]
  }
]

I want to be able to get the expected result as illustrated above.

1 Answers

You are passing a value to groupBy currently not a 'column' to group by. Though you have nested data here so you will need to pass a callback to groupBy where you will return what value the entities should be grouped by:

collect($array['data'])
    ->groupBy(fn ($item) => $item['company']['id']);

Or simply using the 'dot' notation (as mentioned by Donkarnash), since we are starting the collection at the 'data' key:

collect($array['data'])->groupBy('company.id');

Laravel 9.x Docs - Collections - Available Methods - groupBy

Related