MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Pattern-uri de liste

Pattern-urile de liste permit potrivirea expresiilor cu liste și array-uri. Acest pattern este disponibil începând cu versiunea C# 11.

Potrivire completă cu un array/listă:

Console.WriteLine(GetNumber(new[] { 1, 2, 3, 4, 5 }));  // 1
Console.WriteLine(GetNumber(new[] { 1, 2}));            // 3
Console.WriteLine(GetNumber(new int[] {}));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));        // 5

int GetNumber(int[] values) => values switch
{
   [1, 2, 3, 4, 5] => 1,
   [1, 2, 3] => 2,
   [1, 2] => 3,
   [] => 4,
   _ => 5
};

În mod similar, în loc de array-uri se pot folosi liste:

List<int> numbers = new List<int> { 1, 2, 3 };

Console.WriteLine(GetNumber(numbers));  // 2

int GetNumber(List<int> values) => values switch
{
   [1, 2, 3, 4, 5] => 1,
   [1, 2, 3] => 2,
   [1, 2] => 3,
   [] => 4,
   _ => 5
};

De asemenea, pattern-urile de liste pot fi folosite în construcția if:

int[] numbers = { 1, 2, 3, 4, 5 };
if (numbers is [1, 2, 3, 4, 5])
{
   Console.WriteLine("[1, 2, 3, 4, 5]");
}

Substituția _

Cu ajutorul pattern-ului _ se poate desemna un element unic care are orice valoare. De exemplu, pattern-ul [2, _, 5] corespunde oricărui array de trei elemente în care între 2 și 5 se află o valoare arbitrară. Iar array-ul [_, _] corespunde oricărui array de două elemente arbitrare.

Câteva exemple:

Console.WriteLine(GetNumber(new[] { 2, 3, 5 }));      // 1
Console.WriteLine(GetNumber(new[] { 2, 4, 6 }));      // 2
Console.WriteLine(GetNumber(new[] { 1, 2, 5 }));      // 3
Console.WriteLine(GetNumber(new[] { 1, 2, 3 }));      // 4
Console.WriteLine(GetNumber(new int[] { }));          // 5

int GetNumber(int[] values) => values switch
{
   [2, _, 5] => 1,
   [2, _, _] => 2,
   [_, _, 5] => 3,
   [_, _, _] => 4,
   _ => 5
};

Pattern-ul slice

Pentru a transmite un număr arbitrar de elemente din array/listă, se folosește pattern-ul slice ... De exemplu, pattern-ul [1, 2, .., 5] corespunde unui array care începe cu 1, urmat de 2, iar ultimul element din array este 5. Între 2 și 5 poate exista orice număr de valori întregi. Adică, pattern-ul [1, 2, .., 5] va corespunde unor array-uri precum:

int[] arr1 = { 1, 2, 3, 4, 5 };
int[] arr2 = { 1, 2, 5 };
int[] arr3 = { 1, 2, 66, 77, 88, 5 };

Cu ajutorul pattern-ului .. se poate desemna un număr arbitrar de elemente atât la început, cât și la sfârșitul array-ului/listei. De exemplu, pattern-ul [2, ..] reprezintă un array care începe cu 2. Iar pattern-ul [.., 5] reprezintă un array care se termină cu elementul 5. Pattern-ul [..] reprezintă un array care conține un număr arbitrar de elemente. De exemplu:

Console.WriteLine(GetNumber(new[] { 2, 5 }));          // 1
Console.WriteLine(GetNumber(new[] { 2, 3, 4, 5 }));    // 1

Console.WriteLine(GetNumber(new[] { 2 }));             // 2
Console.WriteLine(GetNumber(new[] { 2, 3, 4 }));       // 2

Console.WriteLine(GetNumber(new[] { 3, 4, 5 }));       // 3
Console.WriteLine(GetNumber(new[] { 5 }));             // 3

Console.WriteLine(GetNumber(new int[] { }));           // 4
Console.WriteLine(GetNumber(new[] { 1 }));             // 4
Console.WriteLine(GetNumber(new[] { 1, 2, 3 }));       // 4

int GetNumber(int[] values) => values switch
{
   [2, .., 5] => 1,    // dacă primul element este 2, iar ultimul este 5
   [2, ..] => 2,       // dacă primul element este 2
   [.., 5] => 3,       // dacă ultimul element este 5
   [..] => 4           // număr arbitrar de elemente
};

Pattern-ul slice poate fi combinat cu simboluri de substituție _, de exemplu:

int GetNumber(int[] values) => values switch
{
   [_, .., _] => 1,
   [..] => 2
};

În acest caz, pattern-ul [_, .., _] presupune un array format din cel puțin două elemente arbitrare, iar între primul și ultimul element poate exista un număr arbitrar de alte elemente:

Console.WriteLine(GetNumber(new[] { 1, 2, 3, 4 }));   // 1
Console.WriteLine(GetNumber(new[] { 1, 2, 3 }));      // 1
Console.WriteLine(GetNumber(new[] { 1, 2 }));         // 1
Console.WriteLine(GetNumber(new[] { 1 }));            // 2
Console.WriteLine(GetNumber(new int[] { }));          // 2

int GetNumber(int[] values) => values switch
{
   [_, .., _] => 1,
   [..] => 2
};

Obținerea elementelor în variabile

Valorile individuale din array/listă pot fi obținute în variabile, de exemplu:

int[] numbers = { 2, 3, 5 };
if (numbers is [var first, var second, .., var last])
{
   Console.WriteLine($"first: {first}, second: {second}  last: {last}");
}

În acest caz, obținem primul element al array-ului în variabila first, al doilea element în variabila second, iar ultimul element în variabila last.

Exemplu cu diferite array-uri:

Console.WriteLine(GetData(new[] { 1, 2, 3 }));        // First: 1  Second: 2  Last: 3
Console.WriteLine(GetData(new[] { 2, 4, 6, 8 }));     // First: 2  Second: 4  Last: 8
Console.WriteLine(GetData(new[] { 1, 2 }));           // Array has less than 3 elements

string GetData(int[] values) => values switch
{
   [var first, var second, .., var last] => $"First: {first}  Second: {second}  Last: {last}",
   [..] => "Array has less than 3 elements"
};

În acest caz, obținem primul element al array-ului în variabila first, al doilea element în variabila second, iar ultimul element în variabila last.

În același timp, valorile proiectate pe pattern-ul .. pot fi, de asemenea, obținute într-o variabilă. De exemplu, în pattern-ul [2, .. var middle, 5] elementele proiectate pe .. pot fi transmise în variabila middle. Câteva exemple:

Console.WriteLine(GetSlice(new[] { 2, 3, 4, 5 }));       // Middle: 3, 4
Console.WriteLine(GetSlice(new[] { 2, 4, 6, 8 }));       // End: 4, 6, 8
Console.WriteLine(GetSlice(new[] {

1, 2, 3, 5 }));       // Start: 1, 2, 3
Console.WriteLine(GetSlice(new[] { 1, 2, 3, 4 }));       // All: 1, 2, 3, 4
Console.WriteLine(GetSlice(new int[] { }));              // All:

string GetSlice(int[] values) => values switch
{
   [2, .. var middle, 5] => $"Middle: {string.Join(", ", middle)}",
   [2, .. var end] => $"End: {string.Join(", ", end)}",
   [.. var start, 5] => $"Start: {string.Join(", ", start)}",
   [.. var all] => $"All: {string.Join(", ", all)}"
};

Proprietăți ale colecțiilor

Este de menționat că, deoarece array-urile și listele sunt clase C# obișnuite care au proprietăți, putem aplica pentru ele și pattern-ul de proprietăți. Combinarea pattern-ului de proprietăți și pattern-ului de liste permite simplificarea rezolvării unor sarcini.

De exemplu, avem o sarcină: dacă array-ul are trei elemente, să îl descompunem în trei variabile:

int[] numbers = { 2, 3, 5 };
if (numbers is { Length: 3 } and [var first, var second, var third])
{
   Console.WriteLine($"first: {first}, second: {second}  third: {third}");
}
← Lecția anterioară Lecția următoare →