C# - Evitando loops aninhados com LINQ
Neste artigo veremos como analisar, ou seja, fazer o parse de um arquivo CSV. |
Escrever código pode ser muito interessante, mas também pode ser muito frustrante se o seu código for baseado em loops aninhados visto que as iterações ainda são uma das partes mais importantes na codificação.
Então, como podemos evitar o uso de loops aninhados em nosso código ?
Evitar loops aninhados pode ajudar a tornar o seu código mais limpo, legível e eficiente e dentre as opções para fazer isso vamos focar na utilização da LINQ.
A LINQ ou
Language Integrated Query fornece uma maneira de
expressar consultas diretamente na linguagem C# adicionando expressões de
consulta, que são semelhantes às consultas SQL.
A sintaxe LINQ é geralmente menos eficiente que um loop foreach. Sim, isso
mesmo. Não usamos a LINQ para ter eficiência mas para melhorar a legibilidade do
código.
Assim na maioria das vezes, a LINQ será um pouco mais lento porque apresenta uma sobrecarga. Então não use a LINQ se você se precisa ter desempenho, use-a para ter um código mais enxuto e mais legível e assim facilitar a manutenção.
Quais são então os benefícios da LINQ ?
Seguem alguns...
-
Você pode acessar novas tecnologias sem saber muito sobre elas;
- A LINQ oferece uma maneira baseada em objeto e integrada à linguagem de
consultar dados, não importa de onde esses dados venham. Assim, através do LINQ
podemos consultar banco de dados, XML e coleções.
crie aplicativos completos com menos código
- Permite desenvolver aplicações em menos tempo e com menos erros;
- Permite combinar fontes de dados sem recorrer a truques de programação
estranhos;
- Faz com que novos desenvolvedores trabalhem mais rápido;
- Permite verificar a sintaxe em tempo de compilação;
- Permite consultar coleções como arrays, classes enumeráveis, etc., na
linguagem nativa do seu aplicativo, como VB ou C#, da mesma forma que você
consultaria um banco de dados usando SQL
A seguir temos a anatomia geral de uma consulta usando a LINQ:
variavel = IEnumerable.MetodoLINQ(v=> v.FazAlgumaCoisa());
- variavel
: armazena o resultado
- IEnumerable : List/Array ou outro
IEnumerable
- MetodoLINQ :
Where/Select/SelectMany,Aggregate,Sum,Count, etc.
- v : parâmetro de entrada
- FazAlgumaCoisa : Método que vai
operar em cada elemento da coleção;
Os loops e a LINQ
Vejamos a seguir como substituir loops usando consultas LINQ.
1- Iterar em uma coleção e obter o resultado da multiplação dos itens
int[]
numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; int c = 1;for (int i = 0; i < numeros.Length; ++i) { c *= numeros[i]; } Console.WriteLine("Resultado da multiplicação " + c); |
Usando a LINQ : Método Aggregate com semente
int[]
numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; int resultado = numeros.Aggregate(1, (n1, n2) => n1 * n2);Console.WriteLine(resultado); |
2- Preencher um array onde cada elemento é a soma com o seu anterior e exibir o seu contéudo :
var
vetor =
new
int[100]; for (var n = 0; n < vetor.Length; n++)vetor[n] = n + n; foreach (int x in vetor)Console.Write($"{x} "); |
Usando a LINQ na sintaxe de consulta com Enumerable.Range :
var
vetor = (from n
in
Enumerable.Range(0, 100) select n + n).ToArray(); foreach (int x in vetor)Console.Write($"{x} "); |
3- Loop aninhado com 3 níveis mais difícil de ler e entender:
for
(int
i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { Console.Write($"{k} {j} {i}"); } } } |
Usando a LINQ com Enumerable.Range :
var
numeros =
from I
in
Enumerable.Range(0, 10) from J in Enumerable.Range(0, 10) from K in Enumerable.Range(0, 10) select new { I, J, K }; foreach (var n in numeros){ Console.WriteLine(n); } |
O método Enumerable.Range gera uma sequência de números dentro de um intervalo especificado. Para isso ele usa o método estático Range() da classe Enumerable que esta no namespace System.Linq.
4- Filtrar um array de números inteiros aleatórios que possuem o número 3 :
int[]
numerosAleatorios = { 127, 264, 33657, 43, 535, 6, 83652, 73, 652, 3043,
236, 896 }; List< int> lista = new();foreach (int numero in numerosAleatorios){ if (numero.ToString().Contains("3")) { lista.Add(numero); } } foreach (var n in lista)Console.Write(n + " "); |
Usando a LINQ : consulta com cláusula Where
int[]
numerosAleatorios = { 127, 264, 33657, 43, 535, 6, 83652, 73, 652, 3043,
236, 896 }; var lista = numerosAleatorios.Where(n => n.ToString().Contains("3"));foreach (var n in lista)Console.Write(n + " "); |
Dessa forma, muitas vezes, e, dependendo dos requisitos, as vantagens do LINQ superam as desvantagens.
A perda de velocidade versus uma legibilidade limpa, escrita mais rápida e aplicação de linguagem baseada em SQL sugere que o uso de expressões LINQ oferece benefícios poderosos para o desenvolvedor.
No entanto você deve estar atento para saber decidir quando vale a pena usar as consultas LINQ.
E estamos conversados...
"Bendito seja o Deus e Pai de nosso Senhor Jesus Cristo que, segundo a
sua grande misericórdia, nos gerou de novo para uma viva esperança, pela
ressurreição de Jesus Cristo dentre os mortos"
1 Pedro 1:3
Referências:
Curso Fundamentos da Programação Orientada a Objetos com VB .NET