Laravel Collections: Arrays on stereoids

Laravel además de utilizar múltiples paquetes de terceros tambien es posible utilizar partes como componentes. Todos los componentes están bajo el namespace “Illuminate”.

Si hay una clase realmente interesante y útil es Collection, que nos permite trabajar con arrays de datos de una forma sencilla y “programática”.

Para tener esta clase en nuestro proyecto solo necesitaremos el paquete illuminate/support que podremos instalar con:

composer require illuminate/support:5.2.x-dev

Para mostrar algunos ejemplos utilizaremos un pequeño array con estos datos:

$array = [
    [
        'id' => 12,
        'name' => 'El rinconcillo',
        'category' => 'Bar',
        'visits' => 102,
        'stars' => 4.2,
        'average_price' => 20,
        'city' => 'Sevilla',
        'region' => 'Andalucía',
    ],
    [
        'id' => 30,
        'name' => 'El Choco',
        'category' => 'Bar',
        'visits' => 65,
        'stars' => 4.9,
        'average_price' => 12,
        'city' => 'Pontecesures',
        'region' => 'Galicia',
    ],
    [
        'id' => 89,
        'name' => 'La Azotea',
        'category' => 'Restaurant',
        'visits' => 165,
        'stars' => 4.7,
        'average_price' => 30,
        'city' => 'Sevilla',
        'region' => 'Andalucía',
    ],
    [
        'id' => 22,
        'name' => 'Casa Paco',
        'category' => 'Restaurant',
        'visits' => 15,
        'stars' => 3.7,
        'average_price' => null,
        'city' => 'Sevilla',
        'region' => 'Andalucía',
    ]
];

Con esto crearemos nuestro objeto collection así:

$places = new  Illuminate\Support\Collection(  $array  ) ;

Ahora veremos unos ejemplos de que se puede hacer

Obtener una array (key => value ) con los elementos:

$list = $places->pluck( 'name', 'id')->all() ;

Resultado:

Array
(
    [12] => El rinconcillo
    [30] => El Choco
    [89] => La Azotea
    [22] => Casa Paco
)

Obtener el restaurante con la mayor puntuacion

$best_restaurant = $places
    ->where('category', 'Restaurant')
    ->sortByDesc( 'stars')
    ->take( 1 )
    ->toArray(   );
;

Obtener la suma de visitas por tipo de negocio

$visits_by_category  =  $places
        ->groupBy( 'category')
        ->map( function( $value, $key ) {
        return $value->reduce( function( $prev, $next){
            return $prev + $next['visits'];
        }, 0 );
     })
    ->toArray();

La media de precios, por region, si el precio es nulo no lo tomaremos en consideración:

$average_prices_by_region = $places->groupBy('region')
    ->map(function ($value, $key) {
        return $value->reject(function ($value, $key) {
            return is_null($value['average_price']);
        })
            ->reduce(function ($prev, $next) {
                if ( empty( $prev)) {
                    $prev = $next['average_price'];
                }
                return ( $prev + $next['average_price'] ) / 2  ;
            } );

    })->toArray();

Estos son sólo unos pocos ejemplos que muestran una pequeña parte de las posibilidades de este poderosa clase, y como todo lo de Laravel, dispone de una completa documentación en: https://laravel.com/docs/5.2/collections

comments powered by Disqus