Se você usa Laravel todos os dias ou já usou no passado, você já dever ter percebido como Collections
são uma parte importante se não fundamental do framework.
Alguns sites e até mesmo a própria documentação oficial costumar chamar as Collections
de “Arrays com esteroides” e nesse artigo você vai saber o porque.
Um Array é uma estrutura de dados simples que contém um ou mais elementos em uma única variável. Os arrays em PHP no entanto têm um grande problema, eles não são Orientados a Objetos.
Collections
por sua vez é um poderoso recurso Orientado a Objetos que expande as possibilidades quando se trabalha com arrays em Laravel. Além disso, Collections
nos permite escrever códigos mais eficientes de forma mais fácil.
O método helper collect()
retorna uma novo instancia da classe Illuminate\Support\Collection
. Portanto, criar uma coleção é tão simples quanto:
$collection = collect([1, 2, 3]);
$collection = collect(['produto' => 'Mesa', 'preco' => 200]);
where()
O método where()
filtra uma Collection
por um determinado par chave/valor. Esse método pode receber até três parâmetros, sendo o primeiro a chave que você quer buscar, o operador (=, <>, >=)
e o terceiro parâmetro é o valor que você quer comparar.
Digamos que temos uma loja virtual, e o usuário quer filtrar os produtos por preço, utilizando esse método sua vida fica muito mais simples.
No exemplo abaixo, estamos filtrando todos os produtos com preço igual a R$100.
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$filtrado = $colecao->where('preco', 100);
$filtrado->all();
/*
[
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Armario', 'preco' => 100],
]
*/
Lembrando que o segundo parâmetro da função é o operador se o terceiro parâmetro for omitido, o operador padrão é o =
então você pode mudar para o operador que você precisar, “maior ou igual (>=
) R$100″ por exemplo.
O código abaixo retorna exatamente o mesmo resultado:
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$filtrado = $colecao->where('preco', 100);
$filtrado = $colecao->where('preco', '=', 100);
pluck()
O método pluck()
retorna todos os valores a partir de uma determinada chave. Vou te mostrar o como isso pode ser extremamente útil, considere o mesmo exemplo acima, agora imagine que você precisa de um array contendo apenas o nome de todos os produtos, como você faria? Exatamente, usando pluck()
.
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$filtrado = $colecao->pluck('produto');
$filtrado->all();
/*
['Mesa', 'Cadeira', 'Estante', 'Armario'],
*/
Com esse método você também pode definir qual a chave do valor na resposta, como no exemplo acima só temos duas propriedades em cada item do array, a chave teria que ser preco
.
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$filtrado = $colecao->pluck('produto', 'preco');
$filtrado->all();
/*
[200 => 'Mesa', 100 => 'Cadeira', 150 => 'Estante', 100 => 'Armario'],
*/
Outro fato muito importante desse método que preciso mencionar é que se você tiver um objeto com propriedades aninhadas, você pode usar a notação “dot” para acessar esse valores. Eu explico o que eu quero dizer com o exemplo abaixo:
$colecao = collect([
[
'palestrantes' => [
'primeiro_dia' => ['Rosa', 'Alberto'],
'segundo_dia' => ['Angela', 'Monica'],
],
],
]);
$filtrado = $colecao->pluck('palestrantes.primeiro_dia');
$filtrado->all();
/*
['Rosa', 'Alberto']
*/
Não sei quanto a vocês, mas acho que esse método extremamente útil para diversas situações.
contains()
O método contains()
determina se a coleção contém um determinado item. Você pode passar um função para o método, que vai determinar se existe um elemento na coleção que corresponda a uma determinada condição. Essa é a função mais básica desse método.
$colecao = collect([1, 2, 3, 4, 5]);
$colecao->contains(function ($valor, $chave) {
return $valor > 5;
});
// false
Mais uma vez, vamos usar como exemplo a nossa coleção de produtos. Vamos pensar na situação onde precisamos verificar se temos um determinado produto em nossa loja, poderíamos utilizar esse método, que vai retornar true
ou false
, caso o produto exista na loja ou não.
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$colecao->contains('produto', 'Cadeira');
// true
duplicates()
Outro método que pode ser muito útil é o duplicates()
. Ele recupera e devolve valores duplicados da coleção. Nesse primeiro exemplo, um situação bem simples, mas você já entende como o método funciona.
A coleção abaixo contém 5 elementos, sendo que 2 tem repetições (a, b), o método então retorna um novo array com onde a chave se refere a posição do elemento repetido no array original
$colecao = collect(['a', 'b', 'a', 'c', 'b']);
$colecao->duplicates();
// [2 => 'a', 4 => 'b']
Por exemplo, temos duas letras ‘a’ na coleção, então o método nos retorna [2 => 'a', 4 => 'b']
indicando que temos uma repetição da letra ‘a’ na posição 2 da coleção e repetição da letra ‘b’ na posição 4.
Agora um exemplo mais realístico. Digamos que fizemos cadastro de alguns usuários, mas a validação de email único não estava funcionando perfeitamente e por conta disso temos agora emails duplicados no nosso sistema e precisamos encontrar essas duplicatas, com o método duplicates()
isso se torna um tarefa muito simples:
$usuarios = collect([
['email' => 'rosa@example.com', 'profissao' => 'Gerente de projetos'],
['email' => 'alberto@example.com', 'profissao' => 'Desenvolvedor'],
['email' => 'angela@example.com', 'profissao' => 'Analista de projetos'],
['email' => 'alberto@example.com', 'profissao' => 'Desenvolvedor'],
['email' => 'monica@example.com', 'profissao' => 'Design gráfico'],
['email' => 'alberto@example.com', 'profissao' => 'Desenvolvedor N2'],
]);
$usuarios->duplicates('email');
// [3 => 'alberto@example.com', 5 => 'alberto@example.com']
firstWhere()
O método firstWhere()
retorna o primeiro elemento da coleção com o par chave/valor que corresponde a um valor dado. Nós ja vimos o método where()
, e parece que esse método não faz muito, mas você precisaria de um loop
, um if
e talvez um break
, só para conseguir reproduzir o que esse método faz.
O exemplo abaixo, muito parecido com o exemplo do método where()
, mas ao invés de retornar dois valores, ele nos retorna apenas um, a primeira ocorrência de um produto com valor igual a R$100.
$colecao = collect([
['produto' => 'Mesa', 'preco' => 200],
['produto' => 'Cadeira', 'preco' => 100],
['produto' => 'Estante', 'preco' => 150],
['produto' => 'Armario', 'preco' => 100],
]);
$colecao->firstWhere('preco', 100);
// ['produto' => 'Cadeira', 'preco' => 100]
groupBy()
E o nosso último método da lista o groupBy()
, geralmente é um operação feita diretamente usando SQL no banco de dados, mas nem sempre os dados que queremos manipular vem diretamente de lá, nesse caso podemos utilizar desse método para resolver um problema similar, vejamos como utilizar:
$usuarios = collect([
['nome' => 'Rosa Silva', 'equipe' => 'Back-end'],
['nome' => 'Alberto Junior', 'equipe' => 'Back-end'],
['nome' => 'Angela Maria', 'equipe' => 'Front-end'],
['nome' => 'Tomas Costa', 'equipe' => 'Back-end'],
['nome' => 'Monica Silveira', 'equipe' => 'Front-end'],
['nome' => 'Lucia Oliveira', 'equipe' => 'Front-end'],
]);
$grupos = $usuarios->groupBy('equipe');
// {
// {
// "Back-end": [
// { "nome": "Rosa Silva", "equipe": "Back-end" },
// { "nome": "Alberto Junior", "equipe": "Back-end" },
// { "nome": "Tomas Costa", "equipe": "Back-end"
// ],
// "Front-end": [
// { "nome": "Angela Maria", "equipe": "Front-end" },
// { "nome": "Monica Silveira", "equipe": "Front-end" },
// { "nome": "Lucia Oliveira", "equipe": "Front-end" }
// ]
// }
// }
Como resultado do groupBy()
nessa coleção, agora temos dos arrays, cada um contendo 3 elementos, que corresponde exatamente aos desenvolvedores que fazem parte da equipe do front-end e o no outro array os desenvolvedores do time back-end, como você pode ver, esse método definitivamente da uma ajuda na hora de organizar o seus arrays.
Parabéns pelo artigo e muito obrigado por compartilhar um pouco do seu conhecimento. Muito bom!
Deixe um comentário