Zip în C# (.NET)

LINQ (Language Integrated Query) .NET Framework 4.0 (tuple fără selector: .NET Core 3.0, trei secvențe: .NET 6)

Împerechează elementele a două sau trei secvențe după poziție: primul cu primul, al doilea cu al doilea și așa mai departe.

Sintaxă C#
a.Zip(b)   a.Zip(b, (x, y) => ...)   a.Zip(b, c)

Ce face Zip

Zip parcurge secvențele în paralel și produce câte un rezultat pentru fiecare poziție. Fără funcție, întoarce tuple-uri (First, Second), care se pot deconstrui direct în foreach; cu funcție, întoarce ce calculează ea.

Rezultatul are lungimea celei mai scurte secvențe: elementele în plus din secvența mai lungă sunt ignorate fără eroare. Din .NET 6 poți împerechea trei secvențe, cu tuple-uri (First, Second, Third).

Exemple

Exemplul 1: Elevi și note

string[] elevi = ["Ana", "Mihai", "Ioana"];
int[] note = [9, 7, 10];
string[] orase = ["Iași", "Cluj"];

foreach (var (elev, nota) in elevi.Zip(note))
    Console.WriteLine($"{elev}: {nota}");

foreach (var (elev, nota, oras) in elevi.Zip(note, orase))
    Console.WriteLine($"{elev} din {oras} are {nota}");

Rezultat

Ana: 9
Mihai: 7
Ioana: 10
Ana din Iași are 9
Mihai din Cluj are 7

Exemplul 2: Diferența față de ziua anterioară

Secvența se împerechează cu ea însăși decalată cu un element.

int[] vanzari = [100, 120, 90, 150];

var diferente = vanzari.Zip(vanzari.Skip(1), (ieri, azi) => azi - ieri);
Console.WriteLine(string.Join(", ", diferente));

int[] semestrul1 = [8, 9, 6];
int[] semestrul2 = [9, 9, 8];
Console.WriteLine(string.Join(" ", semestrul1.Zip(semestrul2, (a, b) => a + b)));

Rezultat

20, -30, 60
17 18 14

Greșeli frecvente

  • Presupunerea că Zip dă eroare la lungimi diferite: elementele în plus dispar în tăcere. Verifică lungimile dacă trebuie să fie egale.
  • Zip împerechează după poziție, nu după cheie. Pentru potrivire după ID folosește Join.

Comenzi înrudite

  • Tuple-uri și deconstrucție: Grupează câteva valori fără să declari o clasă: (string Nume, int Varsta), cu deconstrucție în variabile separate.
  • Join: Combină două secvențe după o cheie comună (inner join): fiecare pereche care se potrivește produce un rezultat.
  • Skip / Take (paginare): Take ia primele n elemente, Skip le sare; împreună fac paginare. TakeWhile/SkipWhile se opresc la prima condiție falsă.