Colecciones
Introducción
La clase Illuminate\Support\Collection
proporciona un envoltorio fluido y conveniente para trabajar con arreglos de datos. Por ejemplo, echa un vistazo al siguiente código. Usaremos el helper collect
para crear una nueva instancia de colección a partir del array, ejecutar la función strtoupper
en cada elemento y luego eliminar todos los elementos vacíos:
$collection = collect(['taylor', 'abigail', null])->map(function (?string $name) { return strtoupper($name);})->reject(function (string $name) { return empty($name);});
Como puedes ver, la clase Collection
te permite encadenar sus métodos para realizar un mapeo fluido y la reducción del array subyacente. En general, las colecciones son inmutables, lo que significa que cada método de Collection
devuelve una nueva instancia de Collection
.
Creando Colecciones
Como se mencionó anteriormente, el helper collect
devuelve una nueva instancia de Illuminate\Support\Collection
para el array dado. Así que, crear una colección es tan simple como:
$collection = collect([1, 2, 3]);
[!NOTA] Los resultados de las consultas Eloquent siempre se devuelven como instancias de
Collection
.
Extendiendo Colecciones
Las colecciones son "macroables", lo que te permite agregar métodos adicionales a la clase Collection
en tiempo de ejecución. El método macro
de la clase Illuminate\Support\Collection
acepta una función anónima que se ejecutará cuando se llame a tu macro. La función anónima del macro puede acceder a otros métodos de la colección a través de $this
, así como si fuera un método real de la clase de colección. Por ejemplo, el siguiente código agrega un método toUpper
a la clase Collection
:
use Illuminate\Support\Collection;use Illuminate\Support\Str; Collection::macro('toUpper', function () { return $this->map(function (string $value) { return Str::upper($value); });}); $collection = collect(['first', 'second']); $upper = $collection->toUpper(); // ['FIRST', 'SECOND']
Típicamente, debes declarar macros de colección en el método boot
de un proveedor de servicios.
Argumentos de Macro
Si es necesario, puedes definir macros que acepten argumentos adicionales:
use Illuminate\Support\Collection;use Illuminate\Support\Facades\Lang; Collection::macro('toLocale', function (string $locale) { return $this->map(function (string $value) use ($locale) { return Lang::get($value, [], $locale); });}); $collection = collect(['first', 'second']); $translated = $collection->toLocale('es');
Métodos Disponibles
Para la mayoría de la documentación restante sobre colecciones, discutiremos cada método disponible en la clase Collection
. Recuerda que todos estos métodos se pueden encadenar para manipular de manera fluida el array subyacente. Además, casi todos los métodos devuelven una nueva instancia de Collection
, lo que te permite preservar la copia original de la colección cuando sea necesario:
after all average avg before chunk chunkWhile collapse collect combine concat contains containsOneItem containsStrict count countBy crossJoin dd diff diffAssoc diffAssocUsing diffKeys doesntContain dot dump duplicates duplicatesStrict each eachSpread ensure every except filter first firstOrFail firstWhere flatMap flatten flip forget forPage get groupBy has hasAny implode intersect intersectAssoc intersectByKeys isEmpty isNotEmpty join keyBy keys last lazy macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode multiply nth only pad partition percentage pipe pipeInto pipeThrough pluck pop prepend pull push put random range reduce reduceSpread reject replace replaceRecursive reverse search select shift shuffle skip skipUntil skipWhile slice sliding sole some sort sortBy sortByDesc sortDesc sortKeys sortKeysDesc sortKeysUsing splice split splitIn sum take takeUntil takeWhile tap times toArray toJson transform undot union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap value values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict whereNotNull whereNull wrap zip
Listado de Métodos
after()
El método after
devuelve el elemento después del elemento dado. Se devuelve null
si el elemento dado no se encuentra o es el último elemento:
$collection = collect([1, 2, 3, 4, 5]); $collection->after(3); // 4 $collection->after(5); // null
Este método busca el elemento dado utilizando una comparación "suelta", lo que significa que una cadena que contenga un valor entero se considerará igual a un entero del mismo valor. Para utilizar una comparación "estricta", puedes proporcionar el argumento strict
al método:
collect([2, 4, 6, 8])->after('4', strict: true); // null
collect([2, 4, 6, 8])->after(function (int $item, int $key) { return $item > 5;}); // 8
all()
El método all
devuelve el array subyacente representado por la colección:
collect([1, 2, 3])->all(); // [1, 2, 3]
average()
Alias para el método avg
.
avg()
El método avg
devuelve el valor promedio de una clave dada:
$average = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo'); // 20 $average = collect([1, 1, 2, 4])->avg(); // 2
before()
El método before
es lo opuesto del método after
. Devuelve el elemento antes del elemento dado. Se devuelve null
si no se encuentra el elemento dado o si es el primer elemento:
$collection = collect([1, 2, 3, 4, 5]); $collection->before(3); // 2 $collection->before(1); // null collect([2, 4, 6, 8])->before('4', strict: true); // null collect([2, 4, 6, 8])->before(function (int $item, int $key) { return $item > 5;}); // 4
chunk()
El método chunk
divide la colección en múltiples colecciones más pequeñas de un tamaño dado:
$collection = collect([1, 2, 3, 4, 5, 6, 7]); $chunks = $collection->chunk(4); $chunks->all(); // [[1, 2, 3, 4], [5, 6, 7]]
Este método es especialmente útil en vistas al trabajar con un sistema de cuadrícula como Bootstrap. Por ejemplo, imagina que tienes una colección de modelos Eloquent que deseas mostrar en una cuadrícula:
@foreach ($products->chunk(3) as $chunk) <div class="row"> @foreach ($chunk as $product) <div class="col-xs-4">{{ $product->name }}</div> @endforeach </div>@endforeach
chunkWhile()
El método chunkWhile
divide la colección en múltiples colecciones más pequeñas en función de la evaluación de la devolución de llamada dada. La variable $chunk
pasada a la función anónima
se puede usar para inspeccionar el elemento anterior:
$collection = collect(str_split('AABBCCCD')); $chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) { return $value === $chunk->last();}); $chunks->all(); // [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
collapse()
El método collapse
colapsa una colección de arrays en una sola colección plana:
$collection = collect([ [1, 2, 3], [4, 5, 6], [7, 8, 9],]); $collapsed = $collection->collapse(); $collapsed->all(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
collect()
El método collect
devuelve una nueva instancia de Collection
con los elementos actualmente en la colección:
$collectionA = collect([1, 2, 3]); $collectionB = $collectionA->collect(); $collectionB->all(); // [1, 2, 3]
El método collect
es principalmente útil para convertir colecciones perezosas en instancias de Collection
estándar:
$lazyCollection = LazyCollection::make(function () { yield 1; yield 2; yield 3;}); $collection = $lazyCollection->collect(); $collection::class; // 'Illuminate\Support\Collection' $collection->all(); // [1, 2, 3]
[!NOTE] El método
collect
es especialmente útil cuando tienes una instancia deEnumerable
y necesitas una instancia de colección no perezosa. Dado quecollect()
es parte del contrato deEnumerable
, puedes usarlo con seguridad para obtener una instancia deCollection
.
combine()
El método combine
combina los valores de la colección, como claves, con los valores de otro array o colección:
$collection = collect(['name', 'age']); $combined = $collection->combine(['George', 29]); $combined->all(); // ['name' => 'George', 'age' => 29]
concat()
El método concat
añade los valores del array
o de la colección dada al final de otra colección:
$collection = collect(['John Doe']); $concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']); $concatenated->all(); // ['John Doe', 'Jane Doe', 'Johnny Doe']
El método concat
vuelve a indexar numéricamente las claves de los elementos concatenados a la colección original. Para mantener las claves en colecciones asociativas, consulta el método merge.
contains()
El método contains
determina si la colección contiene un elemento dado. Puedes pasar una función anónima al método contains
para determinar si un elemento existe en la colección que coincide con una prueba de verdad dada:
$collection = collect([1, 2, 3, 4, 5]); $collection->contains(function (int $value, int $key) { return $value > 5;}); // false
Alternativamente, puedes pasar una cadena al método contains
para determinar si la colección contiene un valor de elemento dado:
$collection = collect(['name' => 'Desk', 'price' => 100]); $collection->contains('Desk'); // true $collection->contains('New York'); // false
También puedes pasar un par clave / valor al método contains
, que determinará si el par dado existe en la colección:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->contains('product', 'Bookcase'); // false
El método contains
utiliza comparaciones "sueltas" al verificar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Utiliza el método containsStrict
para filtrar utilizando comparaciones "estrictas".
Para el inverso de contains
, consulta el método doesntContain.
containsOneItem()
El método containsOneItem
determina si la colección contiene un solo elemento:
collect([])->containsOneItem(); // false collect(['1'])->containsOneItem(); // true collect(['1', '2'])->containsOneItem(); // false
containsStrict()
Este método tiene la misma firma que el método contains
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
[!NOTA] El comportamiento de este método se modifica al utilizar Colecciones Eloquent.
count()
El método count
devuelve el número total de elementos en la colección:
$collection = collect([1, 2, 3, 4]); $collection->count(); // 4
countBy()
El método countBy
cuenta las ocurrencias de valores en la colección. Por defecto, el método cuenta las ocurrencias de cada elemento, lo que te permite contar ciertos "tipos" de elementos en la colección:
$collection = collect([1, 2, 2, 2, 3]); $counted = $collection->countBy(); $counted->all(); // [1 => 1, 2 => 3, 3 => 1]
Pasas una función anónima
al método countBy
para contar todos los elementos por un valor personalizado:
$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']); $counted = $collection->countBy(function (string $email) { return substr(strrchr($email, "@"), 1);}); $counted->all(); // ['gmail.com' => 2, 'yahoo.com' => 1]
crossJoin()
El método crossJoin
une los valores de la colección entre los arrays o colecciones dados, devolviendo un producto cartesiano con todas las posibles permutaciones:
$collection = collect([1, 2]); $matrix = $collection->crossJoin(['a', 'b']); $matrix->all(); /* [ [1, 'a'], [1, 'b'], [2, 'a'], [2, 'b'], ]*/ $collection = collect([1, 2]); $matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']); $matrix->all(); /* [ [1, 'a', 'I'], [1, 'a', 'II'], [1, 'b', 'I'], [1, 'b', 'II'], [2, 'a', 'I'], [2, 'a', 'II'], [2, 'b', 'I'], [2, 'b', 'II'], ]*/
dd()
El método dd
volcado los elementos de la colección y finaliza la ejecución del script:
$collection = collect(['John Doe', 'Jane Doe']); $collection->dd(); /* Collection { #items: array:2 [ 0 => "John Doe" 1 => "Jane Doe" ] }*/
Si no deseas detener la ejecución del script, utiliza en su lugar el método dump
.
diff()
El método diff
compara la colección con otra colección o un array
PHP plano en función de sus valores. Este método devolverá los valores en la colección original que no están presentes en la colección dada:
$collection = collect([1, 2, 3, 4, 5]); $diff = $collection->diff([2, 4, 6, 8]); $diff->all(); // [1, 3, 5]
[!NOTA] El comportamiento de este método se modifica al usar Colecciones Eloquent.
diffAssoc()
El método diffAssoc
compara la colección con otra colección o un array
PHP plano en función de sus claves y valores. Este método devolverá los pares clave / valor en la colección original que no están presentes en la colección dada:
$collection = collect([ 'color' => 'orange', 'type' => 'fruit', 'remain' => 6,]); $diff = $collection->diffAssoc([ 'color' => 'yellow', 'type' => 'fruit', 'remain' => 3, 'used' => 6,]); $diff->all(); // ['color' => 'orange', 'remain' => 6]
diffAssocUsing()
A diferencia de diffAssoc
, diffAssocUsing
acepta una función de devolución de llamada suministrada por el usuario para la comparación de índices:
$collection = collect([ 'color' => 'orange', 'type' => 'fruit', 'remain' => 6,]); $diff = $collection->diffAssocUsing([ 'Color' => 'yellow', 'Type' => 'fruit', 'Remain' => 3,], 'strnatcasecmp'); $diff->all(); // ['color' => 'orange', 'remain' => 6]
La función de devolución de llamada debe ser una función de comparación que devuelva un entero menor, igual o mayor que cero. Para obtener más información, consulta la documentación de PHP sobre array_diff_uassoc
, que es la función PHP que utiliza internamente el método diffAssocUsing
.
diffKeys()
El método diffKeys
compara la colección con otra colección o un array
PHP plano basado en sus claves. Este método devolverá los pares de clave / valor en la colección original que no están presentes en la colección dada:
$collection = collect([ 'one' => 10, 'two' => 20, 'three' => 30, 'four' => 40, 'five' => 50,]); $diff = $collection->diffKeys([ 'two' => 2, 'four' => 4, 'six' => 6, 'eight' => 8,]); $diff->all(); // ['one' => 10, 'three' => 30, 'five' => 50]
doesntContain()
El método doesntContain
determina si la colección no contiene un elemento dado. Puedes pasar una función anónima al método doesntContain
para determinar si un elemento no existe en la colección que coincida con una prueba de verdad dada:
$collection = collect([1, 2, 3, 4, 5]); $collection->doesntContain(function (int $value, int $key) { return $value < 5;}); // false
Alternativamente, puedes pasar una cadena al método doesntContain
para determinar si la colección no contiene un valor de ítem dado:
$collection = collect(['name' => 'Desk', 'price' => 100]); $collection->doesntContain('Table'); // true $collection->doesntContain('Desk'); // false
También puedes pasar un par clave / valor al método doesntContain
, lo que determinará si el par dado no existe en la colección:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->doesntContain('product', 'Bookcase'); // true
El método doesntContain
utiliza comparaciones "flexibles" al comprobar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor.
dot()
El método dot
aplana una colección multidimensional en una colección de un solo nivel que utiliza notación "dot" para indicar la profundidad:
$collection = collect(['products' => ['desk' => ['price' => 100]]]); $flattened = $collection->dot(); $flattened->all(); // ['products.desk.price' => 100]
dump()
El método dump
muestra los elementos de la colección:
$collection = collect(['John Doe', 'Jane Doe']); $collection->dump(); /* Collection { #items: array:2 [ 0 => "John Doe" 1 => "Jane Doe" ] }*/
Si deseas detener la ejecución del script después de volcar la colección, utiliza el método dd
en su lugar.
duplicates()
El método duplicates
recupera y devuelve los valores duplicados de la colección:
$collection = collect(['a', 'b', 'a', 'c', 'b']); $collection->duplicates(); // [2 => 'a', 4 => 'b']
Si la colección contiene arrays u objetos, puedes pasar la clave de los atributos que deseas verificar en busca de valores duplicados:
$employees = collect([ ['email' => 'abigail@example.com', 'position' => 'Developer'], ['email' => 'james@example.com', 'position' => 'Designer'], ['email' => 'victoria@example.com', 'position' => 'Developer'],]); $employees->duplicates('position'); // [2 => 'Developer']
duplicatesStrict()
Este método tiene la misma firma que el método duplicates
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
each()
El método each
itera sobre los elementos de la colección y pasa cada elemento a una función anónima:
$collection = collect([1, 2, 3, 4]); $collection->each(function (int $item, int $key) { // ...});
Si deseas dejar de iterar a través de los elementos, puedes devolver false
desde tu función anónima:
$collection->each(function (int $item, int $key) { if (/* condition */) { return false; }});
eachSpread()
El método eachSpread
itera sobre los elementos de la colección, pasando el valor de cada elemento anidado en el callback dado:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]); $collection->eachSpread(function (string $name, int $age) { // ...});
Puedes dejar de iterar a través de los elementos devolviendo false
desde la función de devolución de llamada:
$collection->eachSpread(function (string $name, int $age) { return false;});
ensure()
El método ensure
puede usarse para verificar que todos los elementos de una colección sean de un tipo dado o una lista de tipos. De lo contrario, se lanzará una UnexpectedValueException
:
return $collection->ensure(User::class); return $collection->ensure([User::class, Customer::class]);
Los tipos primitivos como string
, int
, float
, bool
y array
también pueden ser especificados:
return $collection->ensure('int');
[!WARNING] El método
ensure
no garantiza que elementos de diferentes tipos no se añadirán a la colección en un momento posterior.
every()
El método every
se puede usar para verificar que todos los elementos de una colección pasen una prueba de verdad dada:
collect([1, 2, 3, 4])->every(function (int $value, int $key) { return $value > 2;}); // false
Si la colección está vacía, el método every
devolverá verdadero:
$collection = collect([]); $collection->every(function (int $value, int $key) { return $value > 2;}); // true
except()
El método except
devuelve todos los elementos en la colección excepto aquellos con las claves especificadas:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]); $filtered = $collection->except(['price', 'discount']); $filtered->all(); // ['product_id' => 1]
Para la inversa de except
, consulta el método only.
[!NOTA] El comportamiento de este método se modifica al usar Colecciones Eloquent.
filter()
El método filter
filtra la colección utilizando el callback dado, manteniendo solo aquellos elementos que pasan una prueba de verdad dada:
$collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function (int $value, int $key) { return $value > 2;}); $filtered->all(); // [3, 4]
Si no se proporciona ningún callback, se eliminarán todas las entradas de la colección que sean equivalentes a false
:
$collection = collect([1, 2, 3, null, false, '', 0, []]); $collection->filter()->all(); // [1, 2, 3]
Para la inversa de filter
, consulta el método reject.
first()
El método first
devuelve el primer elemento en la colección que pasa una prueba de verdad dada:
collect([1, 2, 3, 4])->first(function (int $value, int $key) { return $value > 2;}); // 3
También puedes llamar al método first
sin argumentos para obtener el primer elemento de la colección. Si la colección está vacía, se devuelve null
:
collect([1, 2, 3, 4])->first(); // 1
firstOrFail()
El método firstOrFail
es idéntico al método first
; sin embargo, si no se encuentra ningún resultado, se lanzará una excepción Illuminate\Support\ItemNotFoundException
:
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) { return $value > 5;}); // Throws ItemNotFoundException...
También puedes llamar al método firstOrFail
sin argumentos para obtener el primer elemento de la colección. Si la colección está vacía, se lanzará una excepción Illuminate\Support\ItemNotFoundException
:
collect([])->firstOrFail(); // Throws ItemNotFoundException...
firstWhere()
El método firstWhere
devuelve el primer elemento en la colección con el par clave / valor dado:
$collection = collect([ ['name' => 'Regena', 'age' => null], ['name' => 'Linda', 'age' => 14], ['name' => 'Diego', 'age' => 23], ['name' => 'Linda', 'age' => 84],]); $collection->firstWhere('name', 'Linda'); // ['name' => 'Linda', 'age' => 14]
También puedes llamar al método firstWhere
con un operador de comparación:
$collection->firstWhere('age', '>=', 18); // ['name' => 'Diego', 'age' => 23]
Al igual que el método where, puedes pasar un argumento al método firstWhere
. En este escenario, el método firstWhere
devolverá el primer elemento donde el valor de la clave del elemento dado sea "truthy":
$collection->firstWhere('age'); // ['name' => 'Linda', 'age' => 14]
flatMap()
El método flatMap
itera a través de la colección y pasa cada valor a la función anónima
dada. La función anónima
puede modificar el elemento y devolverlo, formando así una nueva colección de elementos modificados. Luego, el array se aplana un nivel:
$collection = collect([ ['name' => 'Sally'], ['school' => 'Arkansas'], ['age' => 28]]); $flattened = $collection->flatMap(function (array $values) { return array_map('strtoupper', $values);}); $flattened->all(); // ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
flatten()
El método flatten
aplanará una colección multidimensional en una sola dimensión:
$collection = collect([ 'name' => 'taylor', 'languages' => [ 'php', 'javascript' ]]); $flattened = $collection->flatten(); $flattened->all(); // ['taylor', 'php', 'javascript'];
Si es necesario, puedes pasar un argumento de "profundidad" al método flatten
:
$collection = collect([ 'Apple' => [ [ 'name' => 'iPhone 6S', 'brand' => 'Apple' ], ], 'Samsung' => [ [ 'name' => 'Galaxy S7', 'brand' => 'Samsung' ], ],]); $products = $collection->flatten(1); $products->values()->all(); /* [ ['name' => 'iPhone 6S', 'brand' => 'Apple'], ['name' => 'Galaxy S7', 'brand' => 'Samsung'], ]*/
En este ejemplo, llamar a flatten
sin proporcionar la profundidad también habría aplanado los arrays anidados, resultando en ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']
. Proporcionar una profundidad te permite especificar cuántos niveles de arrays anidados se aplastarán.
flip()
El método flip
intercambia las claves de la colección con sus valores correspondientes:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $flipped = $collection->flip(); $flipped->all(); // ['taylor' => 'name', 'laravel' => 'framework']
forget()
El método forget
elimina un elemento de la colección por su clave:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); // Forget a single key...$collection->forget('name'); // ['framework' => 'laravel'] // Forget multiple keys...$collection->forget(['name', 'framework']); // []
[!WARNING] A diferencia de la mayoría de los otros métodos de colección,
forget
no devuelve una nueva colección modificada; modifica la colección en la que se llama.
forPage()
El método forPage
devuelve una nueva colección que contiene los elementos que estarían presentes en un número de página dado. El método acepta el número de página como su primer argumento y el número de elementos a mostrar por página como su segundo argumento:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]); $chunk = $collection->forPage(2, 3); $chunk->all(); // [4, 5, 6]
get()
El método get
devuelve el elemento en una clave dada. Si la clave no existe, se devuelve null
:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('name'); // taylor
Puedes pasar un valor por defecto opcionalmente como segundo argumento:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']); $value = $collection->get('age', 34); // 34
Incluso puedes pasar una función anónima como el valor predeterminado del método. El resultado de la función anónima se devolverá si la clave especificada no existe:
$collection->get('email', function () { return 'taylor@example.com';}); // taylor@example.com
groupBy()
El método groupBy
agrupa los elementos de la colección por una clave dada:
$collection = collect([ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ['account_id' => 'account-x11', 'product' => 'Desk'],]); $grouped = $collection->groupBy('account_id'); $grouped->all(); /* [ 'account-x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'account-x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ]*/
En lugar de pasar una cadena key
, puedes pasar una función de retorno. La función de retorno debe devolver el valor por el cual deseas agrupar:
$grouped = $collection->groupBy(function (array $item, int $key) { return substr($item['account_id'], -3);}); $grouped->all(); /* [ 'x10' => [ ['account_id' => 'account-x10', 'product' => 'Chair'], ['account_id' => 'account-x10', 'product' => 'Bookcase'], ], 'x11' => [ ['account_id' => 'account-x11', 'product' => 'Desk'], ], ]*/
Se pueden pasar múltiples criterios de agrupación como un array. Cada elemento del array se aplicará al nivel correspondiente dentro de un array multidimensional:
$data = new Collection([ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']], 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],]); $result = $data->groupBy(['skill', function (array $item) { return $item['roles'];}], preserveKeys: true); /*[ 1 => [ 'Role_1' => [ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], ], 'Role_2' => [ 20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']], ], 'Role_3' => [ 10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']], ], ], 2 => [ 'Role_1' => [ 30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']], ], 'Role_2' => [ 40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']], ], ],];*/
has()
El método has
determina si una clave dada existe en la colección:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]); $collection->has('product'); // true $collection->has(['product', 'amount']); // true $collection->has(['amount', 'price']); // false
hasAny()
El método hasAny
determina si alguna de las claves dadas existe en la colección:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]); $collection->hasAny(['product', 'price']); // true $collection->hasAny(['name', 'price']); // false
implode()
El método implode
une elementos en una colección. Sus argumentos dependen del tipo de elementos en la colección. Si la colección contiene arrays u objetos, debes pasar la clave de los atributos que deseas unir y la cadena "glue" que deseas colocar entre los valores:
$collection = collect([ ['account_id' => 1, 'product' => 'Desk'], ['account_id' => 2, 'product' => 'Chair'],]); $collection->implode('product', ', '); // Desk, Chair
Si la colección contiene cadenas simples o valores numéricos, debes pasar el "glue" como el único argumento al método:
collect([1, 2, 3, 4, 5])->implode('-'); // '1-2-3-4-5'
Puedes pasar una función anónima
al método implode
si deseas formatear los valores que se están concatenando:
$collection->implode(function (array $item, int $key) { return strtoupper($item['product']);}, ', '); // DESK, CHAIR
intersect()
El método intersect
elimina cualquier valor de la colección original que no esté presente en el array
o la colección dados. La colección resultante mantendrá las claves de la colección original:
$collection = collect(['Desk', 'Sofa', 'Chair']); $intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']); $intersect->all(); // [0 => 'Desk', 2 => 'Chair']
[!NOTA] El comportamiento de este método se modifica al usar Colecciones Eloquent.
intersectAssoc()
El método intersectAssoc
compara la colección original con otra colección o array
, devolviendo los pares clave / valor que están presentes en todas las colecciones dadas:
$collection = collect([ 'color' => 'red', 'size' => 'M', 'material' => 'cotton']); $intersect = $collection->intersectAssoc([ 'color' => 'blue', 'size' => 'M', 'material' => 'polyester']); $intersect->all(); // ['size' => 'M']
intersectByKeys()
El método intersectByKeys
elimina cualquier clave y sus valores correspondientes de la colección original que no estén presentes en el array
o colección dado:
$collection = collect([ 'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,]); $intersect = $collection->intersectByKeys([ 'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,]); $intersect->all(); // ['type' => 'screen', 'year' => 2009]
isEmpty()
El método isEmpty
devuelve true
si la colección está vacía; de lo contrario, se devuelve false
:
collect([])->isEmpty(); // true
isNotEmpty()
El método isNotEmpty
devuelve true
si la colección no está vacía; de lo contrario, se devuelve false
:
collect([])->isNotEmpty(); // false
join()
El método join
une los valores de la colección con una cadena. Usando el segundo argumento de este método, también puedes especificar cómo se debe añadir el último elemento a la cadena:
collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'collect(['a', 'b'])->join(', ', ' and '); // 'a and b'collect(['a'])->join(', ', ' and '); // 'a'collect([])->join(', ', ' and '); // ''
keyBy()
El método keyBy
indexa la colección por la clave dada. Si múltiples elementos tienen la misma clave, solo el último aparecerá en la nueva colección:
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk'], ['product_id' => 'prod-200', 'name' => 'Chair'],]); $keyed = $collection->keyBy('product_id'); $keyed->all(); /* [ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ]*/
También puedes pasar un callback al método. El callback debe devolver el valor por el cual se debe agrupar la colección:
$keyed = $collection->keyBy(function (array $item, int $key) { return strtoupper($item['product_id']);}); $keyed->all(); /* [ 'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'], ]*/
keys()
El método keys
devuelve todas las claves de la colección:
$collection = collect([ 'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'], 'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],]); $keys = $collection->keys(); $keys->all(); // ['prod-100', 'prod-200']
last()
El método last
devuelve el último elemento en la colección que pasa una prueba de verdad dada:
collect([1, 2, 3, 4])->last(function (int $value, int $key) { return $value < 3;}); // 2
También puedes llamar al método last
sin argumentos para obtener el último elemento de la colección. Si la colección está vacía, se devuelve null
:
collect([1, 2, 3, 4])->last(); // 4
lazy()
El método lazy
devuelve una nueva instancia de LazyCollection
a partir del array subyacente de elementos:
$lazyCollection = collect([1, 2, 3, 4])->lazy(); $lazyCollection::class; // Illuminate\Support\LazyCollection $lazyCollection->all(); // [1, 2, 3, 4]
Esto es especialmente útil cuando necesitas realizar transformaciones en una gran Collection
que contiene muchos elementos:
$count = $hugeCollection ->lazy() ->where('country', 'FR') ->where('balance', '>', '100') ->count();
Al convertir la colección a un LazyCollection
, evitamos tener que asignar una gran cantidad de memoria adicional. Aunque la colección original aún mantiene sus valores en memoria, los filtros posteriores no lo harán. Por lo tanto, prácticamente no se asignará memoria adicional al filtrar los resultados de la colección.
macro()
El método estático macro
te permite añadir métodos a la clase Collection
en tiempo de ejecución. Consulta la documentación sobre extender colecciones para obtener más información.
make()
El método estático make
crea una nueva instancia de colección. Consulta la sección Creando Colecciones.
map()
El método map
itera a través de la colección y pasa cada valor al callback dado. El callback puede modificar el elemento y devolverlo, formando así una nueva colección de elementos modificados:
$collection = collect([1, 2, 3, 4, 5]); $multiplied = $collection->map(function (int $item, int $key) { return $item * 2;}); $multiplied->all(); // [2, 4, 6, 8, 10]
[!WARNING] Al igual que la mayoría de los otros métodos de colección,
map
devuelve una nueva instancia de colección; no modifica la colección sobre la que se llama. Si deseas transformar la colección original, utiliza el métodotransform
.
mapInto()
El método mapInto()
itera sobre la colección, creando una nueva instancia de la clase dada al pasar el valor al constructor:
class Currency{ /** * Create a new currency instance. */ function __construct( public string $code ) {}} $collection = collect(['USD', 'EUR', 'GBP']); $currencies = $collection->mapInto(Currency::class); $currencies->all(); // [Currency('USD'), Currency('EUR'), Currency('GBP')]
mapSpread()
El método mapSpread
itera sobre los elementos de la colección, pasando cada valor de elemento anidado a la función anónima
dada. La función anónima
puede modificar el elemento y devolverlo, formando así una nueva colección de elementos modificados:
$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); $chunks = $collection->chunk(2); $sequence = $chunks->mapSpread(function (int $even, int $odd) { return $even + $odd;}); $sequence->all(); // [1, 5, 9, 13, 17]
mapToGroups()
El método mapToGroups
agrupa los elementos de la colección por la función anónima
dada. La función anónima
debe devolver un array asociativo que contenga un solo par clave / valor, formando así una nueva colección de valores agrupados:
$collection = collect([ [ 'name' => 'John Doe', 'department' => 'Sales', ], [ 'name' => 'Jane Doe', 'department' => 'Sales', ], [ 'name' => 'Johnny Doe', 'department' => 'Marketing', ]]); $grouped = $collection->mapToGroups(function (array $item, int $key) { return [$item['department'] => $item['name']];}); $grouped->all(); /* [ 'Sales' => ['John Doe', 'Jane Doe'], 'Marketing' => ['Johnny Doe'], ]*/ $grouped->get('Sales')->all(); // ['John Doe', 'Jane Doe']
mapWithKeys()
El método mapWithKeys
itera a través de la colección y pasa cada valor al callback dado. El callback debe devolver un array asociativo que contenga un solo par clave / valor:
$collection = collect([ [ 'name' => 'John', 'department' => 'Sales', 'email' => 'john@example.com', ], [ 'name' => 'Jane', 'department' => 'Marketing', 'email' => 'jane@example.com', ]]); $keyed = $collection->mapWithKeys(function (array $item, int $key) { return [$item['email'] => $item['name']];}); $keyed->all(); /* [ 'john@example.com' => 'John', 'jane@example.com' => 'Jane', ]*/
max()
El método max
devuelve el valor máximo de una clave dada:
$max = collect([ ['foo' => 10], ['foo' => 20]])->max('foo'); // 20 $max = collect([1, 2, 3, 4, 5])->max(); // 5
median()
El método median
devuelve el valor mediano de una clave dada:
$median = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->median('foo'); // 15 $median = collect([1, 1, 2, 4])->median(); // 1.5
merge()
El método merge
combina el array o la colección dados con la colección original. Si una clave de cadena en los elementos dados coincide con una clave de cadena en la colección original, el valor del elemento dado sobrescribirá el valor en la colección original:
$collection = collect(['product_id' => 1, 'price' => 100]); $merged = $collection->merge(['price' => 200, 'discount' => false]); $merged->all(); // ['product_id' => 1, 'price' => 200, 'discount' => false]
Si las claves del elemento dado son numéricas, los valores se añadirán al final de la colección:
$collection = collect(['Desk', 'Chair']); $merged = $collection->merge(['Bookcase', 'Door']); $merged->all(); // ['Desk', 'Chair', 'Bookcase', 'Door']
mergeRecursive()
El método mergeRecursive
fusiona el array o la colección dados de manera recursiva con la colección original. Si una clave de cadena en los elementos dados coincide con una clave de cadena en la colección original, entonces los valores de estas claves se fusionan en un array, y esto se hace de manera recursiva:
$collection = collect(['product_id' => 1, 'price' => 100]); $merged = $collection->mergeRecursive([ 'product_id' => 2, 'price' => 200, 'discount' => false]); $merged->all(); // ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
min()
El método min
devuelve el valor mínimo de una clave dada:
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo'); // 10 $min = collect([1, 2, 3, 4, 5])->min(); // 1
mode()
El método mode
devuelve el valor de la moda de una clave dada:
$mode = collect([ ['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->mode('foo'); // [10] $mode = collect([1, 1, 2, 4])->mode(); // [1] $mode = collect([1, 1, 2, 2])->mode(); // [1, 2]
multiply()
El método multiply
crea el número especificado de copias de todos los elementos en la colección:
$users = collect([ ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'],])->multiply(3); /* [ ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ['name' => 'User #1', 'email' => 'user1@example.com'], ['name' => 'User #2', 'email' => 'user2@example.com'], ]*/
nth()
El método nth
crea una nueva colección que consiste en cada n-ésimo elemento:
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']); $collection->nth(4); // ['a', 'e']
Puedes pasar opcionalmente un offset de inicio como segundo argumento:
$collection->nth(4, 1); // ['b', 'f']
only()
El método only
devuelve los elementos en la colección con las claves especificadas:
$collection = collect([ 'product_id' => 1, 'name' => 'Desk', 'price' => 100, 'discount' => false]); $filtered = $collection->only(['product_id', 'name']); $filtered->all(); // ['product_id' => 1, 'name' => 'Desk']
Para la inversa de only
, consulta el método except.
[!NOTA] El comportamiento de este método se modifica al usar Colecciones Eloquent.
pad()
El método pad
rellenará el array con el valor dado hasta que el array alcance el tamaño especificado. Este método se comporta como la función array_pad de PHP.
Para rellenar a la izquierda, debes especificar un tamaño negativo. No se llevará a cabo ningún padding si el valor absoluto del tamaño dado es menor o igual a la longitud del array:
$collection = collect(['A', 'B', 'C']); $filtered = $collection->pad(5, 0); $filtered->all(); // ['A', 'B', 'C', 0, 0] $filtered = $collection->pad(-5, 0); $filtered->all(); // [0, 0, 'A', 'B', 'C']
partition()
El método partition
se puede combinar con la desestructuración de arrays de PHP para separar los elementos que pasan una prueba de verdad dada de aquellos que no:
$collection = collect([1, 2, 3, 4, 5, 6]); [$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) { return $i < 3;}); $underThree->all(); // [1, 2] $equalOrAboveThree->all(); // [3, 4, 5, 6]
percentage()
El método percentage
se puede utilizar para determinar rápidamente el porcentaje de elementos en la colección que pasan una prueba de verdad dada:
$collection = collect([1, 1, 2, 2, 2, 3]); $percentage = $collection->percentage(fn ($value) => $value === 1); // 33.33
Por defecto, el porcentaje se redondeará a dos decimales. Sin embargo, puedes personalizar este comportamiento proporcionando un segundo argumento al método:
$percentage = $collection->percentage(fn ($value) => $value === 1, precision: 3); // 33.333
pipe()
El método pipe
pasa la colección a la función anónima
dada y devuelve el resultado de la función anónima
ejecutada:
$collection = collect([1, 2, 3]); $piped = $collection->pipe(function (Collection $collection) { return $collection->sum();}); // 6
pipeInto()
El método pipeInto
crea una nueva instancia de la clase dada y pasa la colección al constructor:
class ResourceCollection{ /** * Create a new ResourceCollection instance. */ public function __construct( public Collection $collection, ) {}} $collection = collect([1, 2, 3]); $resource = $collection->pipeInto(ResourceCollection::class); $resource->collection->all(); // [1, 2, 3]
pipeThrough()
El método pipeThrough
pasa la colección al array dado de funciones anónimas
y devuelve el resultado de las funciones anónimas
ejecutadas:
use Illuminate\Support\Collection; $collection = collect([1, 2, 3]); $result = $collection->pipeThrough([ function (Collection $collection) { return $collection->merge([4, 5]); }, function (Collection $collection) { return $collection->sum(); },]); // 15
pluck()
El método pluck
recupera todos los valores para una clave dada:
$collection = collect([ ['product_id' => 'prod-100', 'name' => 'Desk'], ['product_id' => 'prod-200', 'name' => 'Chair'],]); $plucked = $collection->pluck('name'); $plucked->all(); // ['Desk', 'Chair']
También puedes especificar cómo deseas que se indexe la colección resultante:
$plucked = $collection->pluck('name', 'product_id'); $plucked->all(); // ['prod-100' => 'Desk', 'prod-200' => 'Chair']
El método pluck
también admite la recuperación de valores anidados utilizando la notación "punto":
$collection = collect([ [ 'name' => 'Laracon', 'speakers' => [ 'first_day' => ['Rosa', 'Judith'], ], ], [ 'name' => 'VueConf', 'speakers' => [ 'first_day' => ['Abigail', 'Joey'], ], ],]); $plucked = $collection->pluck('speakers.first_day'); $plucked->all(); // [['Rosa', 'Judith'], ['Abigail', 'Joey']]
Si existen claves duplicadas, el último elemento coincidente será insertado en la colección extraída:
$collection = collect([ ['brand' => 'Tesla', 'color' => 'red'], ['brand' => 'Pagani', 'color' => 'white'], ['brand' => 'Tesla', 'color' => 'black'], ['brand' => 'Pagani', 'color' => 'orange'],]); $plucked = $collection->pluck('color', 'brand'); $plucked->all(); // ['Tesla' => 'black', 'Pagani' => 'orange']
pop()
El método pop
elimina y devuelve el último elemento de la colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->pop(); // 5 $collection->all(); // [1, 2, 3, 4]
Puedes pasar un número entero al método pop
para eliminar y devolver múltiples elementos del final de una colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->pop(3); // collect([5, 4, 3]) $collection->all(); // [1, 2]
prepend()
El método prepender
añade un elemento al principio de la colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->prepend(0); $collection->all(); // [0, 1, 2, 3, 4, 5]
También puedes pasar un segundo argumento para especificar la clave del elemento añadido al inicio:
$collection = collect(['one' => 1, 'two' => 2]); $collection->prepend(0, 'zero'); $collection->all(); // ['zero' => 0, 'one' => 1, 'two' => 2]
pull()
El método pull
elimina y devuelve un elemento de la colección por su clave:
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']); $collection->pull('name'); // 'Desk' $collection->all(); // ['product_id' => 'prod-100']
push()
El método push
añade un elemento al final de la colección:
$collection = collect([1, 2, 3, 4]); $collection->push(5); $collection->all(); // [1, 2, 3, 4, 5]
put()
El método put
establece la clave y el valor dados en la colección:
$collection = collect(['product_id' => 1, 'name' => 'Desk']); $collection->put('price', 100); $collection->all(); // ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random()
El método random
devuelve un elemento aleatorio de la colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->random(); // 4 - (retrieved randomly)
Puedes pasar un número entero a random
para especificar cuántos elementos te gustaría recuperar aleatoriamente. Siempre se devuelve una colección de elementos al pasar explícitamente el número de elementos que deseas recibir:
$random = $collection->random(3); $random->all(); // [2, 4, 5] - (retrieved randomly)
Si la instancia de la colección tiene menos elementos de los solicitados, el método random
lanzará una InvalidArgumentException
.
El método random
también acepta una función anónima, que recibirá la instancia de la colección actual:
use Illuminate\Support\Collection; $random = $collection->random(fn (Collection $items) => min(10, count($items))); $random->all(); // [1, 2, 3, 4, 5] - (retrieved randomly)
range()
El método range
devuelve una colección que contiene enteros entre el rango especificado:
$collection = collect()->range(3, 6); $collection->all(); // [3, 4, 5, 6]
reduce()
El método reduce
reduce la colección a un solo valor, pasando el resultado de cada iteración a la iteración siguiente:
$collection = collect([1, 2, 3]); $total = $collection->reduce(function (?int $carry, int $item) { return $carry + $item;}); // 6
El valor de $carry
en la primera iteración es null
; sin embargo, puedes especificar su valor inicial pasando un segundo argumento a reduce
:
$collection->reduce(function (int $carry, int $item) { return $carry + $item;}, 4); // 10
El método reduce
también pasa las claves del array en colecciones asociativas al callback dado:
$collection = collect([ 'usd' => 1400, 'gbp' => 1200, 'eur' => 1000,]); $ratio = [ 'usd' => 1, 'gbp' => 1.37, 'eur' => 1.22,]; $collection->reduce(function (int $carry, int $value, int $key) use ($ratio) { return $carry + ($value * $ratio[$key]);}); // 4264
reduceSpread()
El método reduceSpread
reduce la colección a un array de valores, pasando los resultados de cada iteración a la iteración subsecuente. Este método es similar al método reduce
; sin embargo, puede aceptar múltiples valores iniciales:
[$creditsRemaining, $batch] = Image::where('status', 'unprocessed') ->get() ->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) { if ($creditsRemaining >= $image->creditsRequired()) { $batch->push($image); $creditsRemaining -= $image->creditsRequired(); } return [$creditsRemaining, $batch]; }, $creditsAvailable, collect());
reject()
El método reject
filtra la colección utilizando la función anónima
dada. La función anónima
debe devolver true
si el elemento debe ser eliminado de la colección resultante:
$collection = collect([1, 2, 3, 4]); $filtered = $collection->reject(function (int $value, int $key) { return $value > 2;}); $filtered->all(); // [1, 2]
Para la inversa del método reject
, consulta el método filter
.
replace()
El método replace
se comporta de manera similar a merge
; sin embargo, además de sobrescribir elementos coincidentes que tienen claves de cadena, el método replace
también sobrescribirá elementos en la colección que tienen claves numéricas coincidentes:
$collection = collect(['Taylor', 'Abigail', 'James']); $replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']); $replaced->all(); // ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive()
Este método funciona como replace
, pero recursará en los arrays y aplicará el mismo proceso de reemplazo a los valores internos:
$collection = collect([ 'Taylor', 'Abigail', [ 'James', 'Victoria', 'Finn' ]]); $replaced = $collection->replaceRecursive([ 'Charlie', 2 => [1 => 'King']]); $replaced->all(); // ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
reverse()
El método reverse
invierte el orden de los elementos de la colección, preservando las claves originales:
$collection = collect(['a', 'b', 'c', 'd', 'e']); $reversed = $collection->reverse(); $reversed->all(); /* [ 4 => 'e', 3 => 'd', 2 => 'c', 1 => 'b', 0 => 'a', ]*/
search()
El método search
busca en la colección el valor dado y devuelve su clave si se encuentra. Si el elemento no se encuentra, se devuelve false
:
$collection = collect([2, 4, 6, 8]); $collection->search(4); // 1
La búsqueda se realiza utilizando una comparación "suelta", lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Para usar una comparación "estricta", pasa true
como segundo argumento al método:
collect([2, 4, 6, 8])->search('4', strict: true); // false
Alternativamente, puedes proporcionar tu propia función anónima
para buscar el primer elemento que pase una prueba de verdad dada:
collect([2, 4, 6, 8])->search(function (int $item, int $key) { return $item > 5;}); // 2
select()
El método select
selecciona las claves dadas de la colección, similar a una cláusula SELECT
de SQL:
$users = collect([ ['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'], ['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],]); $users->select(['name', 'role']); /* [ ['name' => 'Taylor Otwell', 'role' => 'Developer'], ['name' => 'Victoria Faith', 'role' => 'Researcher'], ],*/
shift()
El método shift
elimina y devuelve el primer elemento de la colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->shift(); // 1 $collection->all(); // [2, 3, 4, 5]
Puedes pasar un número entero al método shift
para eliminar y devolver múltiples elementos del principio de una colección:
$collection = collect([1, 2, 3, 4, 5]); $collection->shift(3); // collect([1, 2, 3]) $collection->all(); // [4, 5]
shuffle()
El método shuffle
mezcla aleatoriamente los elementos en la colección:
$collection = collect([1, 2, 3, 4, 5]); $shuffled = $collection->shuffle(); $shuffled->all(); // [3, 2, 5, 1, 4] - (generated randomly)
skip()
El método skip
devuelve una nueva colección, con el número dado de elementos eliminados del principio de la colección:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $collection = $collection->skip(4); $collection->all(); // [5, 6, 7, 8, 9, 10]
skipUntil()
El método skipUntil
omite elementos de la colección hasta que el callback dado devuelva true
y luego devuelve los elementos restantes en la colección como una nueva instancia de colección:
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipUntil(function (int $item) { return $item >= 3;}); $subset->all(); // [3, 4]
También puedes pasar un valor simple al método skipUntil
para omitir todos los elementos hasta que se encuentre el valor dado:
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipUntil(3); $subset->all(); // [3, 4]
[!WARNING] Si el valor dado no se encuentra o la función de retorno nunca devuelve
true
, el métodoskipUntil
devolverá una colección vacía.
skipWhile()
El método skipWhile
omite elementos de la colección mientras el callback dado devuelve true
y luego devuelve los elementos restantes en la colección como una nueva colección:
$collection = collect([1, 2, 3, 4]); $subset = $collection->skipWhile(function (int $item) { return $item <= 3;}); $subset->all(); // [4]
[!WARNING] Si la función de retorno nunca devuelve
false
, el métodoskipWhile
devolverá una colección vacía.
slice()
El método slice
devuelve un segmento de la colección comenzando en el índice dado:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $slice = $collection->slice(4); $slice->all(); // [5, 6, 7, 8, 9, 10]
Si deseas limitar el tamaño de la porción devuelta, pasa el tamaño deseado como segundo argumento al método:
$slice = $collection->slice(4, 2); $slice->all(); // [5, 6]
El slice devuelto conservará las claves por defecto. Si no deseas preservar las claves originales, puedes usar el método values
para reindexarlas.
sliding()
El método sliding
devuelve una nueva colección de fragmentos que representan una vista de "ventana deslizante" de los elementos en la colección:
$collection = collect([1, 2, 3, 4, 5]); $chunks = $collection->sliding(2); $chunks->toArray(); // [[1, 2], [2, 3], [3, 4], [4, 5]]
Esto es especialmente útil en conjunto con el método eachSpread
:
$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) { $current->total = $previous->total + $current->amount;});
Puedes opcionalmente pasar un segundo valor de "step", que determina la distancia entre el primer elemento de cada fragmento:
$collection = collect([1, 2, 3, 4, 5]); $chunks = $collection->sliding(3, step: 2); $chunks->toArray(); // [[1, 2, 3], [3, 4, 5]]
sole()
El método sole
devuelve el primer elemento de la colección que pasa una prueba de verdad dada, pero solo si la prueba de verdad coincide exactamente con un elemento:
collect([1, 2, 3, 4])->sole(function (int $value, int $key) { return $value === 2;}); // 2
También puedes pasar un par clave / valor al método sole
, que devolverá el primer elemento en la colección que coincide con el par dado, pero solo si coincide exactamente un elemento:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100],]); $collection->sole('product', 'Chair'); // ['product' => 'Chair', 'price' => 100]
Alternativamente, también puedes llamar al método sole
sin argumentos para obtener el primer elemento en la colección si solo hay un elemento:
$collection = collect([ ['product' => 'Desk', 'price' => 200],]); $collection->sole(); // ['product' => 'Desk', 'price' => 200]
Si no hay elementos en la colección que deben ser devueltos por el método sole
, se lanzará una excepción \Illuminate\Collections\ItemNotFoundException
. Si hay más de un elemento que debe ser devuelto, se lanzará una \Illuminate\Collections\MultipleItemsFoundException
.
some()
Alias para el método contains
.
sort()
El método sort
ordena la colección. La colección ordenada mantiene las claves del array original, por lo que en el siguiente ejemplo utilizaremos el método values
para restablecer las claves a índices numerados de forma consecutiva:
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sort(); $sorted->values()->all(); // [1, 2, 3, 4, 5]
Si tus necesidades de ordenación son más avanzadas, puedes pasar un callback a sort
con tu propio algoritmo. Consulta la documentación de PHP sobre uasort
, que es lo que utiliza internamente el método sort
de la colección.
[!NOTA] Si necesitas ordenar una colección de arreglos u objetos anidados, consulta los métodos
sortBy
ysortByDesc
.
sortBy()
El método sortBy
ordena la colección por la clave dada. La colección ordenada mantiene las claves del array original, así que en el siguiente ejemplo usaremos el método values
para restablecer las claves a índices numerados de manera consecutiva:
$collection = collect([ ['name' => 'Desk', 'price' => 200], ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150],]); $sorted = $collection->sortBy('price'); $sorted->values()->all(); /* [ ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ['name' => 'Desk', 'price' => 200], ]*/
El método sortBy
acepta flags de ordenamiento como su segundo argumento:
$collection = collect([ ['title' => 'Item 1'], ['title' => 'Item 12'], ['title' => 'Item 3'],]); $sorted = $collection->sortBy('title', SORT_NATURAL); $sorted->values()->all(); /* [ ['title' => 'Item 1'], ['title' => 'Item 3'], ['title' => 'Item 12'], ]*/
Alternativamente, puedes pasar tu propia función anónima para determinar cómo ordenar los valores de la colección:
$collection = collect([ ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],]); $sorted = $collection->sortBy(function (array $product, int $key) { return count($product['colors']);}); $sorted->values()->all(); /* [ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']], ]*/
Si deseas ordenar tu colección por múltiples atributos, puedes pasar un array de operaciones de ordenación al método sortBy
. Cada operación de ordenación debe ser un array que consista en el atributo por el cual deseas ordenar y la dirección de la ordenación deseada:
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32],]); $sorted = $collection->sortBy([ ['name', 'asc'], ['age', 'desc'],]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ]*/
Al ordenar una colección por múltiples atributos, también puedes proporcionar funciones anónimas
que definan cada operación de ordenación:
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32],]); $sorted = $collection->sortBy([ fn (array $a, array $b) => $a['name'] <=> $b['name'], fn (array $a, array $b) => $b['age'] <=> $a['age'],]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ]*/
sortByDesc()
Este método tiene la misma firma que el método sortBy
, pero ordenará la colección en el orden opuesto.
sortDesc()
Este método ordenará la colección en el orden opuesto al método sort
:
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sortDesc(); $sorted->values()->all(); // [5, 4, 3, 2, 1]
A diferencia de sort
, no puedes pasar una función anónima a sortDesc
. En su lugar, debes usar el método sort
e invertir tu comparación.
sortKeys()
El método sortKeys
ordena la colección por las claves del array asociativo subyacente:
$collection = collect([ 'id' => 22345, 'first' => 'John', 'last' => 'Doe',]); $sorted = $collection->sortKeys(); $sorted->all(); /* [ 'first' => 'John', 'id' => 22345, 'last' => 'Doe', ]*/
sortKeysDesc()
Este método tiene la misma firma que el método sortKeys
, pero ordenará la colección en el orden opuesto.
sortKeysUsing()
El método sortKeysUsing
ordena la colección por las claves del array asociativo subyacente utilizando un callback:
$collection = collect([ 'ID' => 22345, 'first' => 'John', 'last' => 'Doe',]); $sorted = $collection->sortKeysUsing('strnatcasecmp'); $sorted->all(); /* [ 'first' => 'John', 'ID' => 22345, 'last' => 'Doe', ]*/
La función de retorno debe ser una función de comparación que devuelva un número entero menor, igual o mayor que cero. Para obtener más información, consulta la documentación de PHP sobre uksort
, que es la función de PHP que utiliza internamente el método sortKeysUsing
.
splice()
El método splice
elimina y devuelve un fragmento de elementos a partir del índice especificado:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2); $chunk->all(); // [3, 4, 5] $collection->all(); // [1, 2]
Puedes pasar un segundo argumento para limitar el tamaño de la colección resultante:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1); $chunk->all(); // [3] $collection->all(); // [1, 2, 4, 5]
Además, puedes pasar un tercer argumento que contenga los nuevos elementos para reemplazar los elementos eliminados de la colección:
$collection = collect([1, 2, 3, 4, 5]); $chunk = $collection->splice(2, 1, [10, 11]); $chunk->all(); // [3] $collection->all(); // [1, 2, 10, 11, 4, 5]
split()
El método split
divide una colección en el número dado de grupos:
$collection = collect([1, 2, 3, 4, 5]); $groups = $collection->split(3); $groups->all(); // [[1, 2], [3, 4], [5]]
splitIn()
El método splitIn
divide una colección en el número dado de grupos, llenando los grupos no terminales completamente antes de asignar el resto al grupo final:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); $groups = $collection->splitIn(3); $groups->all(); // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
sum()
El método sum
devuelve la suma de todos los elementos en la colección:
collect([1, 2, 3, 4, 5])->sum(); // 15
Si la colección contiene arrays u objetos anidados, debes pasar una clave que se utilizará para determinar qué valores sumar:
$collection = collect([ ['name' => 'JavaScript: The Good Parts', 'pages' => 176], ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],]); $collection->sum('pages'); // 1272
Además, puedes pasar tu propia función anónima
para determinar qué valores de la colección sumar:
$collection = collect([ ['name' => 'Chair', 'colors' => ['Black']], ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']], ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],]); $collection->sum(function (array $product) { return count($product['colors']);}); // 6
take()
El método take
devuelve una nueva colección con el número especificado de elementos:
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(3); $chunk->all(); // [0, 1, 2]
También puedes pasar un número entero negativo para tomar la cantidad especificada de elementos desde el final de la colección:
$collection = collect([0, 1, 2, 3, 4, 5]); $chunk = $collection->take(-2); $chunk->all(); // [4, 5]
takeUntil()
El método takeUntil
devuelve elementos en la colección hasta que el callback dado devuelve true
:
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeUntil(function (int $item) { return $item >= 3;}); $subset->all(); // [1, 2]
También puedes pasar un valor simple al método takeUntil
para obtener los elementos hasta que se encuentre el valor dado:
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeUntil(3); $subset->all(); // [1, 2]
[!WARNING] Si el valor dado no se encuentra o el callback nunca devuelve
true
, el métodotakeUntil
devolverá todos los elementos de la colección.
takeWhile()
El método takeWhile
devuelve elementos de la colección hasta que el callback dado devuelve false
:
$collection = collect([1, 2, 3, 4]); $subset = $collection->takeWhile(function (int $item) { return $item < 3;}); $subset->all(); // [1, 2]
[!WARNING] Si el callback nunca devuelve
false
, el métodotakeWhile
devolverá todos los elementos en la colección.
tap()
El método tap
pasa la colección al callback
dado, lo que te permite "interrumpir" la colección en un punto específico y hacer algo con los elementos sin afectar la colección misma. La colección es luego devuelta por el método tap
:
collect([2, 4, 3, 1, 5]) ->sort() ->tap(function (Collection $collection) { Log::debug('Values after sorting', $collection->values()->all()); }) ->shift(); // 1
times()
El método estático times
crea una nueva colección invocando la función anónima
dada un número especificado de veces:
$collection = Collection::times(10, function (int $number) { return $number * 9;}); $collection->all(); // [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
toArray()
El método toArray
convierte la colección en un array
PHP sencillo. Si los valores de la colección son modelos Eloquent, los modelos también se convertirán en arrays:
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toArray(); /* [ ['name' => 'Desk', 'price' => 200], ]*/
[!WARNING]
toArray
también convierte todos los objetos anidados de la colección que son una instancia deArrayable
a un array. Si quieres obtener el array en crudo subyacente a la colección, utiliza el métodoall
en su lugar.
toJson()
El método toJson
convierte la colección en una cadena serializada en JSON:
$collection = collect(['name' => 'Desk', 'price' => 200]); $collection->toJson(); // '{"name":"Desk", "price":200}'
transform()
El método transform
itera sobre la colección y llama a la devolución de llamada dada con cada elemento de la colección. Los elementos en la colección serán reemplazados por los valores devueltos por la devolución de llamada:
$collection = collect([1, 2, 3, 4, 5]); $collection->transform(function (int $item, int $key) { return $item * 2;}); $collection->all(); // [2, 4, 6, 8, 10]
[!WARNING] A diferencia de la mayoría de los otros métodos de colección,
transform
modifica la colección misma. Si deseas crear una nueva colección en su lugar, utiliza el métodomap
.
undot()
El método undot
expande una colección unidimensional que utiliza notación "dot" en una colección multidimensional:
$person = collect([ 'name.first_name' => 'Marie', 'name.last_name' => 'Valentine', 'address.line_1' => '2992 Eagle Drive', 'address.line_2' => '', 'address.suburb' => 'Detroit', 'address.state' => 'MI', 'address.postcode' => '48219']); $person = $person->undot(); $person->toArray(); /* [ "name" => [ "first_name" => "Marie", "last_name" => "Valentine", ], "address" => [ "line_1" => "2992 Eagle Drive", "line_2" => "", "suburb" => "Detroit", "state" => "MI", "postcode" => "48219", ], ]*/
union()
El método union
añade el array dado a la colección. Si el array dado contiene claves que ya están en la colección original, se preferirán los valores de la colección original:
$collection = collect([1 => ['a'], 2 => ['b']]); $union = $collection->union([3 => ['c'], 1 => ['d']]); $union->all(); // [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique()
El método unique
devuelve todos los elementos únicos en la colección. La colección devuelta mantiene las claves de array originales, así que en el siguiente ejemplo utilizaremos el método values
para restablecer las claves a índices numerados de manera consecutiva:
$collection = collect([1, 1, 2, 2, 3, 4, 2]); $unique = $collection->unique(); $unique->values()->all(); // [1, 2, 3, 4]
Al tratar con arrays u objetos anidados, puedes especificar la clave utilizada para determinar la unicidad:
$collection = collect([ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],]); $unique = $collection->unique('brand'); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ]*/
Finalmente, también puedes pasar tu propia función anónima
al método unique
para especificar qué valor debe determinar la unicidad de un elemento:
$unique = $collection->unique(function (array $item) { return $item['brand'].$item['type'];}); $unique->values()->all(); /* [ ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'], ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'], ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'], ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'], ]*/
El método unique
utiliza comparaciones "sueltas" al verificar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Utiliza el método uniqueStrict
para filtrar utilizando comparaciones "estrictas".
[!NOTA] El comportamiento de este método se modifica al utilizar Colecciones Eloquent.
uniqueStrict()
Este método tiene la misma firma que el método unique
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
unless()
El método unless
ejecutará el callback dado a menos que el primer argumento dado al método evalúe a true
:
$collection = collect([1, 2, 3]); $collection->unless(true, function (Collection $collection) { return $collection->push(4);}); $collection->unless(false, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
Se puede pasar un segundo callback al método unless
. El segundo callback se ejecutará cuando el primer argumento dado al método unless
evalúe a true
:
$collection = collect([1, 2, 3]); $collection->unless(true, function (Collection $collection) { return $collection->push(4);}, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
Para la inversa de unless
, consulta el método when
.
unlessEmpty()
Alias para el método whenNotEmpty
.
unlessNotEmpty()
Alias para el método whenEmpty
.
unwrap()
El método estático unwrap
devuelve los elementos subyacentes de la colección desde el valor dado cuando es aplicable:
Collection::unwrap(collect('John Doe')); // ['John Doe'] Collection::unwrap(['John Doe']); // ['John Doe'] Collection::unwrap('John Doe'); // 'John Doe'
value()
El método value
recupera un valor dado del primer elemento de la colección:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Speaker', 'price' => 400],]); $value = $collection->value('price'); // 200
values()
El método values
devuelve una nueva colección con las claves restablecidas a enteros consecutivos:
$collection = collect([ 10 => ['product' => 'Desk', 'price' => 200], 11 => ['product' => 'Desk', 'price' => 200],]); $values = $collection->values(); $values->all(); /* [ 0 => ['product' => 'Desk', 'price' => 200], 1 => ['product' => 'Desk', 'price' => 200], ]*/
when()
El método when
ejecutará el callback dado cuando el primer argumento proporcionado al método evalúe a true
. La instancia de la colección y el primer argumento dado al método when
se proporcionarán a la función anónima
:
$collection = collect([1, 2, 3]); $collection->when(true, function (Collection $collection, int $value) { return $collection->push(4);}); $collection->when(false, function (Collection $collection, int $value) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 4]
Se puede pasar un segundo callback al método when
. El segundo callback se ejecutará cuando el primer argumento dado al método when
evalúe a false
:
$collection = collect([1, 2, 3]); $collection->when(false, function (Collection $collection, int $value) { return $collection->push(4);}, function (Collection $collection) { return $collection->push(5);}); $collection->all(); // [1, 2, 3, 5]
Para el inverso de when
, consulta el método unless
.
whenEmpty()
El método whenEmpty
ejecutará el callback dado cuando la colección esté vacía:
$collection = collect(['Michael', 'Tom']); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}); $collection->all(); // ['Michael', 'Tom'] $collection = collect(); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}); $collection->all(); // ['Adam']
Se puede pasar una segunda función anónima
al método whenEmpty
que se ejecutará cuando la colección no esté vacía:
$collection = collect(['Michael', 'Tom']); $collection->whenEmpty(function (Collection $collection) { return $collection->push('Adam');}, function (Collection $collection) { return $collection->push('Taylor');}); $collection->all(); // ['Michael', 'Tom', 'Taylor']
Para la inversa de whenEmpty
, consulta el método whenNotEmpty
.
whenNotEmpty()
El método whenNotEmpty
ejecutará el callback dado cuando la colección no esté vacía:
$collection = collect(['michael', 'tom']); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}); $collection->all(); // ['michael', 'tom', 'adam'] $collection = collect(); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}); $collection->all(); // []
Se puede pasar una segunda función anónima
al método whenNotEmpty
que se ejecutará cuando la colección esté vacía:
$collection = collect(); $collection->whenNotEmpty(function (Collection $collection) { return $collection->push('adam');}, function (Collection $collection) { return $collection->push('taylor');}); $collection->all(); // ['taylor']
Para la inversa de whenNotEmpty
, consulta el método whenEmpty
.
where()
El método where
filtra la colección por un par clave / valor dado:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->where('price', 100); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ]*/
El método where
utiliza comparaciones "sueltas" al verificar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Usa el método whereStrict
para filtrar utilizando comparaciones "estrictas".
Opcionalmente, puedes pasar un operador de comparación como segundo parámetro. Los operadores soportados son: '===', '!==', '!=', '==', '=', '<>', '>', '<', '>=', y '<='.
$collection = collect([ ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], ['name' => 'Sue', 'deleted_at' => null],]); $filtered = $collection->where('deleted_at', '!=', null); $filtered->all(); /* [ ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'], ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'], ]*/
whereStrict()
Este método tiene la misma firma que el método where
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
whereBetween()
El método whereBetween
filtra la colección determinando si un valor de elemento especificado está dentro de un rango dado:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 80], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Pencil', 'price' => 30], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereBetween('price', [100, 200]); $filtered->all(); /* [ ['product' => 'Desk', 'price' => 200], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100], ]*/
whereIn()
El método whereIn
elimina elementos de la colección que no tienen un valor de ítem especificado que esté contenido dentro del array dado:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Desk', 'price' => 200], ['product' => 'Bookcase', 'price' => 150], ]*/
El método whereIn
utiliza comparaciones "flexibles" al verificar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Utiliza el método whereInStrict
para filtrar utilizando comparaciones "estrictas".
whereInStrict()
Este método tiene la misma firma que el método whereIn
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
whereInstanceOf()
El método whereInstanceOf
filtra la colección por un tipo de clase dado:
use App\Models\User;use App\Models\Post; $collection = collect([ new User, new User, new Post,]); $filtered = $collection->whereInstanceOf(User::class); $filtered->all(); // [App\Models\User, App\Models\User]
whereNotBetween()
El método whereNotBetween
filtra la colección determinando si un valor de elemento especificado está fuera de un rango dado:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 80], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Pencil', 'price' => 30], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereNotBetween('price', [100, 200]); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 80], ['product' => 'Pencil', 'price' => 30], ]*/
whereNotIn()
El método whereNotIn
elimina elementos de la colección que tienen un valor de ítem especificado que está contenido dentro del array dado:
$collection = collect([ ['product' => 'Desk', 'price' => 200], ['product' => 'Chair', 'price' => 100], ['product' => 'Bookcase', 'price' => 150], ['product' => 'Door', 'price' => 100],]); $filtered = $collection->whereNotIn('price', [150, 200]); $filtered->all(); /* [ ['product' => 'Chair', 'price' => 100], ['product' => 'Door', 'price' => 100], ]*/
El método whereNotIn
utiliza comparaciones "libres" al verificar los valores de los elementos, lo que significa que una cadena con un valor entero se considerará igual a un entero del mismo valor. Usa el método whereNotInStrict
para filtrar utilizando comparaciones "estrictas".
whereNotInStrict()
Este método tiene la misma firma que el método whereNotIn
; sin embargo, todos los valores se comparan utilizando comparaciones "estrictas".
whereNotNull()
El método whereNotNull
devuelve elementos de la colección donde la clave dada no es null
:
$collection = collect([ ['name' => 'Desk'], ['name' => null], ['name' => 'Bookcase'],]); $filtered = $collection->whereNotNull('name'); $filtered->all(); /* [ ['name' => 'Desk'], ['name' => 'Bookcase'], ]*/
whereNull()
El método whereNull
devuelve elementos de la colección donde la clave dada es null
:
$collection = collect([ ['name' => 'Desk'], ['name' => null], ['name' => 'Bookcase'],]); $filtered = $collection->whereNull('name'); $filtered->all(); /* [ ['name' => null], ]*/
wrap()
El método estático wrap
envuelve el valor dado en una colección cuando es aplicable:
use Illuminate\Support\Collection; $collection = Collection::wrap('John Doe'); $collection->all(); // ['John Doe'] $collection = Collection::wrap(['John Doe']); $collection->all(); // ['John Doe'] $collection = Collection::wrap(collect('John Doe')); $collection->all(); // ['John Doe']
zip()
El método zip
fusiona los valores del array dado con los valores de la colección original en su índice correspondiente:
$collection = collect(['Chair', 'Desk']); $zipped = $collection->zip([100, 200]); $zipped->all(); // [['Chair', 100], ['Desk', 200]]
Mensajes de Mayor Orden
Las colecciones también ofrecen soporte para "mensajes de orden superior", que son atajos para realizar acciones comunes en colecciones. Los métodos de la colección que proporcionan mensajes de orden superior son: average
, avg
, contains
, each
, every
, filter
, first
, flatMap
, groupBy
, keyBy
, map
, max
, min
, partition
, reject
, skipUntil
, skipWhile
, some
, sortBy
, sortByDesc
, sum
, takeUntil
, takeWhile
, y unique
.
Cada mensaje de orden superior se puede acceder como una propiedad dinámica en una instancia de colección. Por ejemplo, usemos el mensaje de orden superior each
para llamar a un método en cada objeto dentro de una colección:
use App\Models\User; $users = User::where('votes', '>', 500)->get(); $users->each->markAsVip();
Del mismo modo, podemos usar el mensaje de orden superior sum
para recopilar el número total de "votos" para una colección de usuarios:
$users = User::where('group', 'Development')->get(); return $users->sum->votes;
Colecciones Pérezosas
Introducción
[!WARNING] Antes de aprender más sobre las colecciones perezosas de Laravel, tómate un tiempo para familiarizarte con los generadores de PHP. Para complementar la ya poderosa clase
Collection
, la claseLazyCollection
aprovecha los generadores de PHP para permitirte trabajar con conjuntos de datos muy grandes mientras mantienes bajo el uso de memoria. Por ejemplo, imagina que tu aplicación necesita procesar un archivo de registro de varios gigabytes mientras aprovecha los métodos de colección de Laravel para analizar los registros. En lugar de leer todo el archivo en memoria de una vez, se pueden usar colecciones perezosas para mantener solo una pequeña parte del archivo en memoria en un momento dado:
use App\Models\LogEntry;use Illuminate\Support\LazyCollection; LazyCollection::make(function () { $handle = fopen('log.txt', 'r'); while (($line = fgets($handle)) !== false) { yield $line; }})->chunk(4)->map(function (array $lines) { return LogEntry::fromLines($lines);})->each(function (LogEntry $logEntry) { // Process the log entry...});
O, imagina que necesitas iterar a través de 10,000 modelos Eloquent. Al usar colecciones tradicionales de Laravel, todos los 10,000 modelos Eloquent deben cargarse en memoria al mismo tiempo:
use App\Models\User; $users = User::all()->filter(function (User $user) { return $user->id > 500;});
Sin embargo, el método cursor
del generador de consultas devuelve una instancia de LazyCollection
. Esto te permite seguir ejecutando una sola consulta contra la base de datos, pero también mantener solo un modelo Eloquent cargado en memoria a la vez. En este ejemplo, el callback filter
no se ejecuta hasta que realmente iteramos sobre cada usuario de forma individual, lo que permite una drástica reducción en el uso de memoria:
use App\Models\User; $users = User::cursor()->filter(function (User $user) { return $user->id > 500;}); foreach ($users as $user) { echo $user->id;}
Creando Colecciones Perezosas
Para crear una instancia de colección perezosa, debes pasar una función generadora de PHP al método make
de la colección:
use Illuminate\Support\LazyCollection; LazyCollection::make(function () { $handle = fopen('log.txt', 'r'); while (($line = fgets($handle)) !== false) { yield $line; }});
El Contrato Enumerable
Casi todos los métodos disponibles en la clase Collection
también están disponibles en la clase LazyCollection
. Ambas clases implementan el contrato Illuminate\Support\Enumerable
, que define los siguientes métodos:
all average avg chunk chunkWhile collapse collect combine concat contains containsStrict count countBy crossJoin dd diff diffAssoc diffKeys dump duplicates duplicatesStrict each eachSpread every except filter first firstOrFail firstWhere flatMap flatten flip forPage get groupBy has implode intersect intersectAssoc intersectByKeys isEmpty isNotEmpty join keyBy keys last macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode nth only pad partition pipe pluck random reduce reject replace replaceRecursive reverse search shuffle skip slice sole some sort sortBy sortByDesc sortKeys sortKeysDesc split sum take tap times toArray toJson union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict wrap zip
Métodos de Colección Perezosa
Además de los métodos definidos en el contrato Enumerable
, la clase LazyCollection
contiene los siguientes métodos:
takeUntilTimeout()
El método takeUntilTimeout
devuelve una nueva colección perezosa que enumerará valores hasta el tiempo especificado. Después de ese tiempo, la colección dejará de enumerar:
$lazyCollection = LazyCollection::times(INF) ->takeUntilTimeout(now()->addMinute()); $lazyCollection->each(function (int $number) { dump($number); sleep(1);}); // 1// 2// ...// 58// 59
Para ilustrar el uso de este método, imagina una aplicación que envía facturas desde la base de datos utilizando un cursor. Podrías definir una tarea programada que se ejecute cada 15 minutos y procese solo facturas durante un máximo de 14 minutos:
use App\Models\Invoice;use Illuminate\Support\Carbon; Invoice::pending()->cursor() ->takeUntilTimeout( Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes') ) ->each(fn (Invoice $invoice) => $invoice->submit());
tapEach()
Mientras que el método each
llama al callback dado para cada elemento en la colección de inmediato, el método tapEach
solo llama al callback dado a medida que se extraen los elementos de la lista uno por uno:
// Nothing has been dumped so far...$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) { dump($value);}); // Three items are dumped...$array = $lazyCollection->take(3)->all(); // 1// 2// 3
throttle()
El método throttle
limitará la colección perezosa de modo que cada valor se devuelva después del número especificado de segundos. Este método es especialmente útil en situaciones donde puede estar interactuando con API externas que limitan la tasa de solicitudes entrantes:
use App\Models\User; User::where('vip', true) ->cursor() ->throttle(seconds: 1) ->each(function (User $user) { // Call external API... });
remember()
El método remember
devuelve una nueva colección perezosa que recordará cualquier valor que ya haya sido enumerado y no los volverá a recuperar en enumeraciones de colección posteriores:
// No query has been executed yet...$users = User::cursor()->remember(); // The query is executed...// The first 5 users are hydrated from the database...$users->take(5)->all(); // First 5 users come from the collection's cache...// The rest are hydrated from the database...$users->take(20)->all();