.NET 6 -  LINQ  - Usando o método Chunk


Hoje vou apresentar o novo método de extensão Chunk da LINQ disponível no .NET 6.

A LINQ recebeu alguma atenção durante o desenvolvimento do .NET 6 e várias novas extensões foram adicionadas.

Esses recursos foram incluídos no .NET 6 preview 4, portanto, para usar essas novas extensões, você precisa instalar esta versão do .NET 6 ou mais recente. E para ter uma  melhor experiência do desenvolvedor, você também precisa da versão mais recente do Visual Studio 2022.

Hoje eu vou tratar especificamente do novo método de extensão Chunk.

O novo método de extensão Chunk

A palavra Chunk pode ser traduzida como 'fatiar', 'retirar um pedaço' e expressa a ideia de como o método atua.

Usando o método Chunk podemos 'fatiar' ou 'pegar um pedaço' de uma coleção maior.

Antes, quando você queria dividir uma coleção grande, precisava usar loops e lógica condicional.

Vejamos a sintaxe do método:

public static System.Collections.Generic.IEnumerable<TSource[]> Chunk<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, int size);

Dessa forma ao usar o método Chunk estamos definindo em quantas fatias desejamos dividir a coleção.

Exemplo prático

Vamos criar uma coleção com 50 números aleatórios e a seguir vamos fatiar essas coleção em 5 fatias com coleções de 10 elementos cada usando o método Chunk.

Abaixo temos o código para criar a coleção com 50 números aleatórios:

List<int> numeros = new();

int contador = 0;

Random rand = new(DateTime.Now.Milisecond);

while (contador < 50)
{
    numeros.Add(rand.Next(1, 1000));
    contador++;
}

foreach(int numero in numeros)
    Console.Write($"{numero}\t ");

 

A seguir vamos fatiar essa coleção em fatias de 10 elementos cada o que nos dá 5 fatias.

Abaixo temos o código que fatia a coleção e a seguir percorre cada fatia exibindo os elementos de cada fatia:

var fatias = numeros.Chunk(10);

var tamanho = fatias.Count();

Console.WriteLine($"\nNúmero de fatias : {tamanho} \n");

Console.WriteLine("Percorrendo cada fatia \n");

for(int i = 0; i< tamanho;i++)
{
    Console.Write($"fatia {i} \t ");
    Resultado(fatias.ElementAt(i));
}

Criando um projeto Console (.NET Core) no .NET 6 temos o código completo usado:

Console.WriteLine("### LINQ usando Chunk()--------------\n");
Console.WriteLine("Coleção de número que desejamos fatiar...\n");

List<int> numeros = new();

int contador = 0;

Random rand = new(DateTime.Now.Millisecond);

while (contador < 50)
{
    numeros.Add(rand.Next(1, 1000));
    contador++;
}

foreach(int numero in numeros)
    Console.Write($"{numero}\t ");

Console.WriteLine("\n\nPressione algo para fatiar a coleção em 5 fatias\n");
Console.WriteLine("Assim cada fatia vai possuir 10 elementos\n");

Console.ReadKey();

var fatias = numeros.Chunk(10);

var tamanho = fatias.Count();

Console.WriteLine($"\nNúmero de fatias : {tamanho} \n");

Console.WriteLine("Percorrendo cada fatia \n");

for(int i = 0; i< tamanho;i++)
{
    Console.Write($"fatia {i} \t ");
    Resultado(fatias.ElementAt(i));
}

void Resultado(IEnumerable<int> numeros)
{
    foreach (var numero in numeros)
        Console.Write($"{numero} \t");
    Console.WriteLine();
}

Console.ReadKey();

 

Neste código estamos usando o novo recurso do C# 9 Top Level Statements.

Executando o projeto teremos o seguinte resultado:

Observe que temos 5 coleções com 10 elementos obtidas a partir do método Chunk.

Pergunta que não quer calar...

O que acontece se o tamanho das fatias não se dividem igualmente no número de elementos da coleção original ?

Vamos supor que queremos dividir a coleção de 50 números inteiros em fatias com 7 elementos cada.

Em quantas fatias(coleções) isso resulta e quantos elementos cada coleção irá conter ?

O resultado final será 8 fatias ou coleções sendo que as 7 primeiras fatias terão 7 elementos e a última fatia terá apenas 1 elemento.

Isso é obtido dividindo 50 por 7 e considerando o resto.

Abaixo o resultado para este caso:



Agora temos 7 fatias com 7 elementos e 1 fatia com 1 elemento.

Esteja ciente desse comportamento se precisar agrupar coleções de tamanhos ímpares.

Pegue o código completo aqui: Linq_Chunk.zip

"E, ao pôr do sol, todos os que tinham enfermos de várias doenças lhos traziam; e, pondo as mãos sobre cada um deles, 'Jesus' os curava."
Lucas 4:40


Referências:


José Carlos Macoratti