I have now come up with an own solution to this:
1. Created a general function to extract specific attributes from arrays
The function below extract only specific attributes from an associative array, or an array of associative arrays (the last is what you get when doing $collection->toArray() in Laravel).
It can be used like this:
$data = array_extract( $collection->toArray(), ['id','url'] );
I am using the following functions:
function array_is_assoc( $array )
{
return is_array( $array ) && array_diff_key( $array, array_keys(array_keys($array)) );
}
function array_extract( $array, $attributes )
{
$data = [];
if ( array_is_assoc( $array ) )
{
foreach ( $attributes as $attribute )
{
$data[ $attribute ] = $array[ $attribute ];
}
}
else
{
foreach ( $array as $key => $values )
{
$data[ $key ] = [];
foreach ( $attributes as $attribute )
{
$data[ $key ][ $attribute ] = $values[ $attribute ];
}
}
}
return $data;
}
This solution does not focus on performance implications on looping through the collections in large datasets.
2. Implement the above via a custom collection i Laravel
Since I would like to be able to simply do $collection->extract('id','url');
on any collection object, I have implemented a custom collection class.
First I created a general Model, which extends the Eloquent model, but uses a different collection class. All you models need to extend this custom model, and not the Eloquent Model then.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Lib\Collection;
class Model extends EloquentModel
{
public function newCollection(array $models = [])
{
return new Collection( $models );
}
}
?>
Secondly I created the following custom collection class:
<?php
namespace Lib;
use Illuminate\Support\Collection as EloquentCollection;
class Collection extends EloquentCollection
{
public function extract()
{
$attributes = func_get_args();
return array_extract( $this->toArray(), $attributes );
}
}
?>
Lastly, all models should then extend your custom model instead, like such:
<?php
namespace App\Models;
class Article extends Model
{
...
Now the functions from no. 1 above are neatly used by the collection to make the $collection->extract()
method available.
Collection::implode()
. It can take a property and extract it from all the objects in the collection. This doesn't answer this question exactly, but it might be useful for others who have come here from Google, as I did. laravel.com/docs/5.7/collections#method-implode – musicin3dUsers::get()->except(['password', 'secret_answer']);
– Cameron Wilby