Use map() instead of each() to affect the collection in-situ.
return $items->groupBy('group_field')->map(function ($group) {
$group->sortBy('sort_property');
});
Hello,
(UPDATE: in a laravel 6 code base)
I think I'm missing something while trying to sort a "multi-dimensional" (or nested) collection.
Initially I have a list of models which I groupBy() a given field they all have, lets say 'group_field'.
This gives me a collection of the models now grouped under each one's group_field.
- group_field
-- Model id:1, sort_property: 2
-- Model id:3, sort_property: 1
- group_field
-- Model id:2, sort_property: 1
-- Model id:4, sort_property: 3
-- Model id:7, sort_property: 2
- group_field
-- Model id:5, sort_property: 2
-- Model id:6, sort_property: 1
Internally each model also contains a sort property (not cleverly named 'sort').
I'd like to sortBy() that internal property after grouping the models together, but it seems like it is "ignoring" the sortBy methods. I just need to sort them in-place and return the entire collection further down the line to a blade view or what ever.
// this is how I'm grouping
return $items->groupBy('group_field');
Shouldn't now a sortBy/sortByDesc method on each group sort the "items" internally without the need to return or cast to an array/collection?
// silly example that does not work
return
$items->groupBy('group_field')->each(function($group) {
$group->sortBy('sort_property');
});
// expected result
- group_field
-- Model id:3, sort_property: 1
-- Model id:1, sort_property: 2
- group_field
-- Model id:2, sort_property: 1
-- Model id:7, sort_property: 2
-- Model id:4, sort_property: 3
- group_field
-- Model id:6, sort_property: 1
-- Model id:5, sort_property: 2
I've also tried passing a callback to the sortBy() method but I still get the original grouped collection with the internal items in their original order. What am I missing?
// Dumping in place shows correctly sorted list.
$items->groupBy('group_field')->each(function($group) {
dump($group->sortBy('sort_property')); // I can see them sorted.
});
return $items; // not sorted anymore.
// or
dd($items); // not sorted
I'm clearly doing something wrong.
After leaving my last post I went back to the documentation and read this..
sortBy()
The sortBy method sorts the collection by the given key. The sorted collection keeps the original array keys, so in this example we'll use the values method to reset the keys to consecutively numbered indexes:
I just had to return with values()->all() after sorting...
And that is what I was missing. I guess dd() was doing something similar to the collection when converting it to an array, but return was "reverting" to sort by the keys inside the group.
Silly me.
Please or to participate in this conversation.