Vinicius Quaiato

{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}

Zip novo extension do LINQ


Salve galera do mal! O Linq no .NET 4 traz uma nova extension: Zip. Ao contrário do que possa parecer Zip não é dos arquivos .zip compactados. Este extension method aplicado a qualquer IEnumerable faz o merge de dois IEnumerable em um terceiro IEnumerable, e o resultado pode ser de um tipo diferente dos outros dois. A assinatura desta extension é:

public
static IEnumerable<tresult> Zip<TFirst, TSecond, TResult>(this IEnumerable<tfirst> first,IEnumerable<tsecond> second,Func<TFirst, TSecond, TResult> resultSelector)

Usando o Zip

Imaginem o seguinte caso:

string[] times = { "Santos", "Santo André", "Grêmio Prudente", "São Paulo", "Corinthians" }
;
    int[] classifica = { 1, 2, 3, 4 }
;

Queremos que os 4 primeiros times se classifiquem, e queremos obter a posição de cada um deles. Com o Zip podemos fazer algo assim:

string[] times = { "Santos", "Santo André", "Grêmio Prudente", "São Paulo", "Corinthians" }
;
    int[] classifica = { 1, 2, 3, 4 }
;
var timesClassificados = times.Zip(classifica, (t, c) => Tuple.Create(t, c));

Na linha 3 o que fizemos é chamar a extension Zip. Passamos então o IEnumerable classifica (1,2,3,4). O segundo argumento é uma Func que recebe 2 parâmetros. O primeiro deles vindo da coleção times, e o segundo vindo de classifica. Então o que fazemos é criar uma Tuple com eses dois valores.O objeto timesClassificados contém 4 items, como pode ser visto abaixo:Resultado da utilização do Zip

Eu poderia não criar uma Tuple, poderia criar uma string simplesmente:

var timesClassificados = times.Zip(classifica, (t, c) => string.Format("{
}
 - {
}
", c, t));

E teríamos o mesmo resultado.Ainda poderia usar Linq ao invés de extensions:

string[] times = { "Santos", "Santo André", "Grêmio Prudente", "São Paulo", "Corinthians", "Portuguesa" }
;
    int[] classifica = { 1, 2, 3, 4, 5, 6 }
;
var timesClassificados = from item in times.Zip(classifica, (t, c) => new { Time = t, Posicao = c }
)                         where item.Posicao <= 4                         select item;

No exemplo acima, criamos 6 times e 6 posições. Chamamos a extension Zip na linha 4 e então criamos um tipo anônimo. Na linha 5 dizemos que queremos apenas os 4 primeiros times. E então temos o mesmo resultado anterior.Dá pra brincar bastante com o Zip. Não é nada sensacional, mas pra quem precisa fazer uns merges meio malucos com coleções, pode tirar proveito desta novidade.Mais informações podem ser obtidas aqui no MSDN.aspx), aqui neste blog e aqui neste outro blog.É isso, abraços e se divirtam!

Att, Vinicius Quaiato.

Voltar

Fork me on GitHub