LINQ - Usando ToDictionary() e ToList() - II
Hoje vamos continuar a mostrar a utilização dos métodos de extensão ToDictionary() e ToList() da LINQ. |
Continuando a primeira parte do artigo vamos tratar com o método ToDictionary().
LINQ : Usando ToDictionary()
Se ToList() pega um IEnumerable<T> e o converte em List<T>, adivinhe o que ToDictionary() faz..?
Basicamente, ToDictionary() é um método muito útil para pegar os resultados de uma consulta (ou qualquer IEnumerable <T>) e organizá-los em um Dictionary<TKey, TValue>.
O truque é definir
como o T é convertido em TKey e TValue respectivamente.
Digamos que temos nossa lista de produtos e queremos colocá-la em um
Dictionary<int, Produto> para que possamos obter os
tempos de pesquisa mais rápidos possíveis com base no ID.
Bem, você poderia fazer algo assim:
var produtos = Produto.GetProdutos();
var resultado = new Dictionary<int, Produto>();
foreach (var produto in produtos)
{
resultado.Add(produto.Id, produto);
}
|
Mas este código seria uma redundância pois basta duas linhas de código para obter o mesmo resultado:
var produtos = Produto.GetProdutos();
var resultado1 = produtos.ToDictionary(prod => prod.Id, prod => prod.Nome);
|
Podemos confirmar o examinando o valor de resultado1:
Este código cria um Dictionary<int, string> onde a
chave é a propriedade Id e o valor é a propriedade
Nome de cada Produto. Como você pode ver, este
método tem muito poder para processar IEnumerable<T>
a partir de uma coleção ou de um resultado de consulta em um dicionário.
E se eu precisar de um dicionário que contenha listas de grupos lógicos ?
Então, em nosso exemplo, digamos que queremos criar um Dictionary<string, List<Produto>> de modo que a chave seja uma Categoria e o valor seja a lista de todos os produtos nessa categoria.
Bem, se você gosta de exercício físico pode teclar este código:
static void Main(string[] args)
{
var produtos = Produto.GetProdutos();
var resultado = new Dictionary<string, List<Produto>>();
foreach (var produto in produtos)
{
List<Produto> subLista;
// Se não tem a categoria cria uma nova lista e incluir no dicionario
if (!resultado.TryGetValue(produto.Categoria, out subLista))
{
subLista = new List<Produto>();
resultado.Add(produto.Categoria, subLista);
}
//inclui o produto na nova sublista
subLista.Add(produto);
}
Console.ReadLine();
}
|
Criamos um monte de código para fazer algo simples.
Felizmente, podemos aproveitar as vantagens de ToDictionary () e ToList() para simplificar e com a ajuda do método de extensão LINQ GroupBy() vamos obter o mesmo resultado com o seguinte código:
var produtos = Produto.GetProdutos();
var resultado = produtos.GroupBy(prod => prod.Categoria)
.ToDictionary(group => group.Key, group => group.ToList());
|
Executando o código e examinando o valor de resultado vamos constatar o seguinte:
No código a cláusula GroupBy() é a consulta de expressão LINQ que cria um IGrouping com um campo Key e também é um IEnumerable dos itens no grupo.
Assim que fizemos
GroupBy(), tudo o que tivemos que fazer foi
converter esses grupos em um dicionário, então nosso seletor de chave (group
=> group.Key) pega o campo de agrupamento (Categoria) e o torna a
chave no dicionário, e o seletor de valor (group => group.ToList ()) pega
os itens do grupo e os converte em uma List<Produto>
como o valor do nosso dicionário!
Muito mais fácil de ler e escrever e muito menos código para manter e testar.
Pegue o projeto completo aqui : Linq_ToListToDictionary2.zip
"Mas o fruto do
Espírito é: amor, gozo, paz, longanimidade, benignidade, bondade, fé, mansidão,
temperança.
Contra estas coisas não há lei."
Gálatas 5:22,23
Referências:
LINQ - Revisando conceitos básicos
LINQ Operadores
C# - Um pouco mais sobre LINQ Queries
LINQ - Consultas LINQ