Dicas C# - Usando o LINQ para contar frequências em listas
Olá caros leitores,
Exemplo completo no final do post!
O que veremos neste post:
Extrair no C# de forma ágil e elegante a frequência de itens em uma lista de objeto complexo.
Para tal, utilizaremos o Linq.
Cenario:
Em uma situação que se tem uma lista de objetos complexos ( Boletos, Usuários, Livros etc ) e deseja-se obter a quantidade de ocorrências de uma determinada propriedade da lista.
Com isto podemos fazer todo tipo de agrupamento e extração de dados de ocorrências de forma simples.
Imagine o objeto que traz as notas dos alunos em disciplinas e queremos saber a ocorrência e as notas somente em matemática.
1. Contrução do Objeto: AlunoDisciplinaNota
public class AlunoDisciplinaNota{
public int Id {get;set;}
public int Nota {get;set;}
public string Disciplina {get;set;}
}
2. Agora vamos criar uma lista com tipos complexos:
List<AlunoDisciplinaNota> alunos = new List<AlunoDisciplinaNota>()
{ new AlunoDisciplinaNota() { Id = 1, Nota = 10, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 2, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 3, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 4, Nota = 10, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 5, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 6, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 7, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 8, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 9, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 10, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 1, Nota = 10, Disciplina = "Português"},
new AlunoDisciplinaNota() { Id = 2, Nota = 1, Disciplina = "Português"},
new AlunoDisciplinaNota() { Id = 3, Nota = 1, Disciplina = "Português"},
};
3. Retorno esperado:
List<AlunoDisciplinaNota> alunos = new List<AlunoDisciplinaNota>()
{ new AlunoDisciplinaNota() { Id = 1, Nota = 10, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 2, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 3, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 4, Nota = 10, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 5, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 6, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 7, Nota = 2, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 8, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 9, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 10, Nota = 9, Disciplina = "Matemática"},
new AlunoDisciplinaNota() { Id = 1, Nota = 10, Disciplina = "Português"},
new AlunoDisciplinaNota() { Id = 2, Nota = 1, Disciplina = "Português"},
new AlunoDisciplinaNota() { Id = 3, Nota = 1, Disciplina = "Português"},
};
3. Retorno esperado:
Ocorrências em Matemática
Nota = 10 | Ocorrências = 2
Nota = 2 | Ocorrências = 5
Nota = 9 | Ocorrências = 3
Excluindo-se da conta os 3 itens da lista que são referentes à Português:
...
new AlunoDisciplinaNota() { Id = 1, Nota = 10, Disciplina = "Português"}, new AlunoDisciplinaNota() { Id = 2, Nota = 1, Disciplina = "Português"}, new AlunoDisciplinaNota() { Id = 3, Nota = 1, Disciplina = "Português"}, ...
4. Execução:
.Where(x => x.Disciplina == "Matemática") // Filtra o resultado somente por matemática
Utilizando Linq temos de forma simples nosso objetivo:
var query1 = from a in alunos
.Where(x => x.Disciplina == "Matemática")
group a by a.Nota into g
select new {Count = g.Count(), Nota = g.Key};
5. Explicando o código acima:
var query1 = from a in alunos // Coloca na variável query1 a lista de alunos
var query1 = from a in alunos
.Where(x => x.Disciplina == "Matemática")
group a by a.Nota into g
select new {Count = g.Count(), Nota = g.Key};
5. Explicando o código acima:
var query1 = from a in alunos // Coloca na variável query1 a lista de alunos
.Where(x => x.Disciplina == "Matemática") // Filtra o resultado somente por matemática
group a by a.Nota into g // Faz uma nova lista que é agrupamento somente pela nota na variável g
select new {Count = g.Count(), Nota = g.Key}; // faz o retorno do resultado em query1 que agora será uma lista com os campos Count e Nota, resultado do agrupamento.
6. Para provar, executa-se um foreach em query1 exibindo os seus 2 campos:
Console.WriteLine("Ocorrências em Matemática \n");
foreach (var n in query1)
{
Console.WriteLine("Nota = {0} | Ocorrências = {1}", n.Nota, n.Count);
}
Pronto! Temos nossa extração de ocorrências.
Abaixo vc confere o código final:
Comentários
Postar um comentário