Hi,
Just started to play with collections Illuminate\Support\Collection.
I was wanting to run something over the collection to modify each of the results, after trying to use each() with no success I found that map() did what I wanted, but returned a new array, not a modified collection. I have had a look at the code and found that this here is the problem;
https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Collection.php#L94
/**
* Execute a callback over each item.
*
* @param Closure $callback
* @return \Illuminate\Support\Collection
*/
public function each(Closure $callback)
{
array_map($callback, $this->items);
return $this;
}
Line 94 is the array_map(). I have tested locally and believe that it should have been $this->items = array_map($callback, $this->items);. This way you are modifying the items as array_map() returns a new array of items, it doesn't modify the input.
This would mean the function looks like;
/**
* Execute a callback over each item.
*
* @param Closure $callback
* @return \Illuminate\Support\Collection
*/
public function each(Closure $callback)
{
$this->items = array_map($callback, $this->items);
return $this;
}
You most likely want Collection::map() https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Collection.php#L272,
Collection::each() most likely work as array_walk() or foreach.
Please read what I wrote, I have used map but I don't want a new array, I want to modify the existing.
There is transform I believe?
There is transform I believe?
Then what the hell is each for ?
i think that the behavior is okay,
if the array_map is assign to $this->items
if you want to apply change and have a new collection without modify the original, use each() if not use map()
@Anahkiasen each may just be used as an iterator over all items. It being implemented using array_map is just an implementation detail, it gives the desired output.
transform is the same as map but affects the collection instance itself, whereas map returns a new instance of the modified collection.
an example of the code I am using is as follows;
$family = Collection::make([
'dad' => ['age' => 42],
'mam' => ['age' => 39],
'son' => ['age' => 12],
]);
print $family->each(function(array $person) {
$person['age'] = (int)$person['age'] + 10;
$person['location'] = 'here';
return $person;
})->toJson(JSON_PRETTY_PRINT);
What I would expect here would be something like;
{
"dad": [
"age": 52,
"location": "here"
],
"mam": [
"age": 49,
"location": "here"
],
"son": [
"age": 22,
"location": "here"
],
}
I want to modify the existing collection and a logical name for this to me would be each. This is because I want to do something to each of the items
You want transform, as was mentioned before.
On 22 May 2014 18:36, "Alan Wynn" [email protected] wrote:
an example of the code I am using is as follows;
$family = Collection::make([
'dad' => ['age' => 42],
'mam' => ['age' => 39],
'son' => ['age' => 12],]);
print json_encode($family->each(function(array $person) {
$person['age'] = (int)$person['age'] + 10;
$person['location'] = 'here';}), JSON_PRETTY_PRINT);What I would expect here would be something like;
{
"dad": [
"age": 52,
"location": "here"
],
"mam": [
"age": 49,
"location": "here"
],
"son": [
"age": 22,
"location": "here"
],}I want to modify the existing collection and a logical name for this to me
would be each. This is because I want to do something to each of the items—
Reply to this email directly or view it on GitHubhttps://github.com/laravel/framework/issues/4472#issuecomment-43864406
.
Thanks, but this then makes me ask how does each work? Because array_map() returns an array, how does the function work? Any examples?
It uses array_map but does not assign the result to the collections items.
It's purpose is iterate over each item in the collection, useful for
calling another method with the value of each item.
On 22 May 2014 19:03, "Alan Wynn" [email protected] wrote:
Thanks, but this then makes me ask how does each work? Because array_map()returns an array, how does the function work? Any examples?
—
Reply to this email directly or view it on GitHubhttps://github.com/laravel/framework/issues/4472#issuecomment-43866648
.
Thanks for clearing that up
@djekl what about if you send the parameter $person to the closure by reference?
$family->each(function(array &$person) ?
Collection::transform() is what I wanted. I just misunderstood the class https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Collection.php#L526
Most helpful comment
Then what the hell is
eachfor ?