0

Already received a great answer at this post

Laravel Query using GroupBy with distinct traits

But how can I modify it to include more than just one field. The example uses pluck which can only grab one field.

I have tried to do something like this to add multiple fields to the view as such...

$hats = $hatData->groupBy('style')
->map(function ($item){
  return ['colors' => $item->color, 'price' => $item->price,'itemNumber'=>$item->itemNumber];
});

In my initial query for "hatData" I can see the fields are all there but yet I get an error saying that 'colors', (etc.) is not available on this collection instance. I can see the collection looks different than what is obtained from pluck, so it looks like when I need more fields and cant use pluck I have to format the map differently but cant see how. Can anyone explain how I can request multiple fields as well as output them on the view rather than just one field as in the original question? Thanks!

weekapaug
  • 332
  • 1
  • 4
  • 15

1 Answers1

1

When you use groupBy() of Laravel Illuminate\Support\Collection it gives you a deeper nested arrays/objects, so that you need to do more than one map on the result in order to unveil the real models (or arrays).

I will demo this with an example of a nested collection:

$collect = collect([
        collect([
            'name' => 'abc',
            'age' => 1
        ]),collect([
            'name' => 'cde',
            'age' => 5
        ]),collect([
            'name' => 'abcde',
            'age' => 2
        ]),collect([
            'name' => 'cde',
            'age' => 7
        ]),
    ]);

    $group = $collect->groupBy('name')->values();

    $result =  $group->map(function($items, $key){

              // here we have uncovered the first level of the group 
              // $key is the group names which is the key to each group

                 return $items->map(function ($item){

                 //This second level opens EACH group (or array) in my case:

                    return $item['age'];
                });
    });

The summary is that, you need another loop map(), each() over the main grouped collection.

  • can you tell me if I need to add this step with collect() to my query? Lets say all my data is already retrieved in a query called hatData. Do I need to do something with this collect([ ... ]) command? – weekapaug Oct 18 '17 at 18:01
  • No, your query result is already a collection, I used `collect()` because I wanted to replicate a sample result of db query. In your case you'll have collections-of-collections-of-models after you use `groupBy()` - note the 2-steps... – Oluwatobi Samuel Omisakin Oct 18 '17 at 18:04
  • If you want to debug the issue, you can try the example I gave. Check for yourself the result after `groupBy()` so you can understand what to expect and do to the data better. – Oluwatobi Samuel Omisakin Oct 18 '17 at 18:05
  • the question I have left after reading all this is since I want 2 values, I only see age, where would I ask for name in this loop? I need a better understanding of how to get the multiple values, like 3, since I understand the top level group is "name" but then there are multiple values beneath that. Such as Name then followed by say age and sex – weekapaug Oct 18 '17 at 19:07
  • You can also pick those attributes as well, I only use `age` as an example. You can pick as many as possible i.e the attributes in the model. – Oluwatobi Samuel Omisakin Oct 18 '17 at 19:42
  • What I mean is how to format the multiples IE.. return $item['age']; return $item['sex']; or how do I ask for more than one. The example only shows the group and one item, Im having issue with proper syntax for multiples – weekapaug Oct 18 '17 at 19:57
  • You simply return it like the example in your question, i.e, `return ['age' => $item['age'], 'name'$ => item['name']];` You may want to check the documentation for further understanding: https://laravel.com/docs/5.5/collections – Oluwatobi Samuel Omisakin Oct 19 '17 at 07:20