Binu
Binu

Reputation: 83

Laravel collection incrementing inside map not possible with arrow function

I'm trying to increment during the map method, however my variable doesn't seem to save the new value. My code:

$position = 0;

$statement = $medias->map(fn(string $media) => [
                'position' => ++$position
            ])->values();

My expected result would be:

#items: array:4 [
    0 => array:4 [
      "position" => 1
    ]
    1 => array:4 [
      "position" => 2
    ]
    2 => array:4 [
      "position" => 3
    ]
    3 => array:4 [
      "position" => 4
    ]
  ]

However it's actually

 #items: array:4 [
        0 => array:4 [
          "position" => 1
        ]
        1 => array:4 [
          "position" => 1
        ]
        2 => array:4 [
          "position" => 1
        ]
        3 => array:4 [
          "position" => 1
        ]
      ]

Is incrementing inside map not possible or am I doing something wrong here?

Upvotes: 3

Views: 1717

Answers (1)

rez
rez

Reputation: 2087

The problem here is that you expect $position variable to be passed by reference, which is not the case.

Arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x) for every variable $x used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope. Anonymous functions can be used instead for by-ref bindings. PHP Manual - Arrow Functions

A workaround for you could be like this:

// Either
$posObj = new \stdClass();
$posObj->position = 0;
// or
$posObj = (object)array('position' => 0);

$statement = $medias->map(fn(string $media) => [
                'position' => ++$posObj->position
            ])->values();

Upvotes: 1

Related Questions