Usando Laravel versión 5.4.

Código:

collect(['3a', '4b'])->map('intval')->all();

Resultado esperado: [3, 4]

Pero, en cambio, la línea anterior devuelve [3, 0], es decir, el primer elemento se transforma correctamente, mientras que el segundo no.

¿Que esta pasando aqui?

Cabe destacar que obtengo el resultado correcto con la función php array_map nativa:

// returns [3, 4]
array_map('intval', ['3a', '4b']);
1
Sergey Neskhodovskiy 21 oct. 2017 a las 12:06

3 respuestas

La mejor respuesta

Para entender exactamente lo que está sucediendo, podemos verificar el código fuente de la clase Colección donde encontramos la función de mapa

public function map(callable $callback)
{
    $keys = array_keys($this->items);

    $items = array_map($callback, $this->items, $keys);

    return new static(array_combine($keys, $items));
}

Entonces, ¿qué laravel agrega realmente las claves también a la llamada a la función array_map, que finalmente produce esta llamada array_map('intval', ['3a', '4b'], [0, 1])

Esto llamará a intval('3a', 0) y intval('4b', 1) respectivamente, lo que, como se esperaba, producirá 3 y 0, porque el segundo parámetro de intval de acuerdo con documentos oficiales de PHP es en realidad la base.

Laravel agrega las claves porque a veces puede usarlas en su devolución de llamada de mapa como tal

$collection->map(function($item, $key) { ... });
2
Tudor 21 oct. 2017 a las 09:22

Acabo de probarlo, esto sucede porque map() pasa las claves de colección como tercer argumento:

array_map($callback, $this->items, $keys);

Así que:

array_map('intval', ['3a', '4b'], [0, 1]); // Result is [3, 0]
array_map('intval', ['3a', '4b']); // Result is [3, 4]
1
Alexey Mezenin 21 oct. 2017 a las 09:19

Si intenta de acuerdo con la sintaxis del mapa de colección laravel, produce el resultado esperado

collect(['3a', '4b'])->map(function($item){
   return intval($item);
})->all();

Resultado

[3,4]
1
Shobi 21 oct. 2017 a las 09:15