I'm trying to sort nested collection but i can't get correct results.
category tags collection
[
{
"id": 1,
"name": "Age",
"tags": [
{
"id": 1,
"name": "18 "
},
{
"id": 2,
"name": "21 "
},
{
"id": 3,
"name": "25 "
},
{
"id": 4,
"name": "30 "
},
{
"id": 5,
"name": "17 "
},
{
"id": 6,
"name": "16 "
},
{
"id": 7,
"name": "26 "
},
{
"id": 8,
"name": "13 "
},
{
"id": 9,
"name": "24 "
},
{
"id": 10,
"name": "20 "
},
{
"id": 11,
"name": "19 "
}
],
}
]
i'm trying to sort tags:
<?php
$categoryTagsSorted = $categoryTags->transform(
function ($categoryTag) {
$sortedTags = $categoryTag->tags->sortBy('name');
// $sortedTags->values() return correct sorted array
$categoryTag->tags = $sortedTags->values();// < - this not work
return $categoryTag;
}
);
$categoryTagsSorted
returns untouched results, but when i assign $sortedTags
to $categoryTag->newField = $sortedTags->values()
i've got sorted tags in newField
.
Question is how to return collection with sorted tags?
CodePudding user response:
you can try this :
$categoryTagsSorted = $categoryTags->each(
function ($categoryTag) {
$categoryTag = $categoryTag->tags->sortBy('name');
}
);
CodePudding user response:
In your code I believe you have misunderstood the use of the transform()
method. It is used to iterate over each item in the collection and replaces the item with the value you give it in the callback. In your code you have also simply returned the original value without applying any 'transformation' to it. If you wish to alter the value of tags on the object you could try reassigning the object property:
$categoryTags->tags = $categoryTags->tags->sortBy('name');
Read the docs on the transform
method here: https://laravel.com/docs/9.x/collections#method-transform#
Update
I think you can simply use map
and re-assign the tags property to accomplish the solution:
$categoryTags->map(function($categoryTag) {
$categoryTag->tags = $categoryTag->tags->sortBy('name');
return $categoryTag;
});
The following test code worked OK for me...
$categoryTags = collect([
(object) [
'id' => 1,
'name' => 'Age',
'tags' => collect([
['id' => 1, 'name' => '18 '],
['id' => 2, 'name' => '21 '],
['id' => 3, 'name' => "25 "],
['id' => 4, 'name' => "30 "],
['id' => 5, 'name' => "17 "]
])
]
]);
$categoryTags->map(function($categoryTag) {
$categoryTag->tags = $categoryTag->tags->sortBy('name');
return $categoryTag;
});
var_dump($categoryTags);
Output:
object(Illuminate\Support\Collection)#1029 (1) {
["items":protected]=>
array(1) {
[0]=>
object(stdClass)#1030 (3) {
["id"]=>
int(1)
["name"]=>
string(3) "Age"
["tags"]=>
object(Illuminate\Support\Collection)#1026 (1) {
["items":protected]=>
array(5) {
[4]=>
array(2) {
["id"]=>
int(5)
["name"]=>
string(3) "17 "
}
[0]=>
array(2) {
["id"]=>
int(1)
["name"]=>
string(3) "18 "
}
[1]=>
array(2) {
["id"]=>
int(2)
["name"]=>
string(3) "21 "
}
[2]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(3) "25 "
}
[3]=>
array(2) {
["id"]=>
int(4)
["name"]=>
string(3) "30 "
}
}
}
}
}
}
=> null
Try it out here: https://web.tinkerwell.app/#/snippets/e2c93c20-5706-4ffd-bcc0-601aae861c8b (takes a min to load)