3

I declared a variable of collect() data type. I want to iterate through it, and to update specific column on each row.

The example code:

    $a = collect([
        ['one' => 1, 'two' => 2],
        ['one' => 3, 'two' => 4],
        ['one' => 5, 'two' => 6]
    ]);

    foreach ($a as $b) {
        $b['one'] = 0;
    }

    dd($a);

I don't understand, why the result is this:


Collection {#510 ▼
  #items: array:3 [▼
    0 => array:2 [▼
      "one" => 1
      "two" => 2
    ]
    1 => array:2 [▼
      "one" => 3
      "two" => 4
    ]
    2 => array:2 [▼
      "one" => 5
      "two" => 6
    ]
  ]
}

I expect "one" => 0 as a result for each row.

miken32
  • 42,008
  • 16
  • 111
  • 154
TheVic
  • 303
  • 6
  • 16
  • the same for array: $a = [['one' => 1, 'two' => 2], ['one' => 3, 'two' => 4], ['one' => 5, 'two' => 6]]; – TheVic Mar 26 '19 at 08:47

1 Answers1

4

You are not modifying the original array, there is no place where you store the modified item back to the array. For this purpose it is better to use the map function on the collection itself.

$a = collect([['one' => 1, 'two' => 2], ['one' => 3, 'two' => 4], ['one' => 5, 'two' => 6]]);

$a = $a->map(function($item) { 
    $item['one'] = 0; 
    return $item; 
});

The for each way:

foreach ($a as $key => $b) {
   $b['one'] = 0;
   $a[$key] = $b; // override the original item.
}
nakov
  • 13,938
  • 12
  • 60
  • 110
  • 1
    Thank you for explanation. This kind of weird for me, is this an Laravel specific(PHP)? I never observed something like this in other languages. – TheVic Mar 26 '19 at 08:54
  • 2
    No it is not. If you use for each, you get hold of an item on each iteration but in order to modify the original array you need to put the modified item back to the original array. Look at my edit. – nakov Mar 26 '19 at 08:57
  • Thank you again. Now I understand it completely. – TheVic Mar 26 '19 at 09:01
  • 2
    Technically this is called pass by value instead of pass by reference, which means you don't get access to the original reference but to a copy of it. In PHP you can use & in front of the variable, for example &$a will modify the original array (the reference). Glad it helped. Happy coding :) – nakov Mar 26 '19 at 09:04