LINQ i kolekcje obiektów - Tworzenie nowych obiektów  Udostępnij na: Facebook

Autor: Paweł Sołtysiak

Opublikowano: 2012-03-15

Operator zapytań LINQ o nazwie Select służy do tworzenia nowej kolekcji, bazującej na już istniejącej. Może posłużyć jako narzędzie do przetworzenia istniejącej kolekcji obiektów. Dzięki temu, że korzysta on z typów anonimowych, nie ma potrzeby pisania klas, które miałyby przechowywać dane. Podobnie jak reszta operatorów LINQ, Select służy do uproszczenia kodu, dzięki czemu nasz program jest krótszy oraz czytelniejszy.

Przed wykonaniem zadań powinieneś wiedzieć:

  • jak utworzyć nowy projekt konsolowy w języku C# w Visual Studio (od wersji 2008),
  • jak posługiwać się tablicami oraz kolekcjami,
  • jak wyszukiwać obiekty w LINQ.

Po wykonaniu zadań nauczysz się:

  • jak przekształcić kolekcję obiektów,
  • jak połączyć dane z dwóch tabel przy użyciu operatora Select,
  • jak utworzyć typ anonimowy przy użyciu operatora Select,
  • jak połączyć w pary elementy z dwóch tablic.

Implementacja

W Visual Studio (od wersji 2008) utwórz nowy projekt konsolowy dla języka C#.

Twoim zadaniem będzie sprawdzenie, jak działa operator Select.

Operator Select – prosta transformacja tablicy

W celu utworzenia nowej kolekcji obiektów, składającej się z kwadratów liczb kolekcji wejściowej, użyjemy operatora Select,

  1. Otwórz plik o nazwie Program.cs
  2. Wewnątrz funkcji Main wpisz:
var numbers = new[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numbersSquared = from number in numbers
                     select number * number;

foreach (var number in numbersSquared)
{
    Console.WriteLine(number);
}
  1. Uruchom program za pomocą Debug -> Start Without Debugging (Ctrl+F4).
  2. Powinien uruchomić się program wyświetlający kwadraty liczby z tablicy numbers. Sytuacja została zaprezentowana na Rys. 1.

Rys. 1. Liczby z nowej kolekcji.

Informacja
Po słowie kluczowym select definiujemy, w jaki sposób ma zostać utworzona nowa kolekcja. W tym przykładzie, każdą liczbę mnożymy przez siebie i w rezultacie otrzymujemy kwadrat liczby.

Połączenie danych z dwóch tabel

Operator Select może posłużyć do połączenia danych z dwóch kolekcji.

  1. Zamień kod z poprzedniego zadania następującym kodem:
var numbers = new[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var digits = new[] { "zero", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem", "osiem", "dziewięć" };
var numbersName = from number in numbers
                  select digits[number];
foreach (var name in numbersName)
{
    Console.WriteLine(name);
}
  1. Uruchom program za pomocą Debug -> Start Without Debugging (Ctrl+F4).
  2. Powinien uruchomić się program wyświetlający liczebniki odpowiadające liczbom z tablicy. Sytuację przedstawiono na Rys. 2.

Rys. 2. Liczebniki opowiadają liczbom znajdującym się w tablicy numbers.

Informacja
Dopasowanie liczebnika do liczby polega na dopasowaniu liczby z tabeli numbers, którą używamy jako indeks dla tabeli digits, w której znajdują się liczebniki.

Korzystanie z typów anonimowych

Typy anonimowe służą do enkapsulacji danych wewnątrz obiektów, które nie trzeba wcześniej definiować. Typy anonimowe wykorzystuje się najczęściej, gdy chcemy połączyć kilka danych ze sobą.

  1. Zamień kod z poprzedniego zadania następującym kodem:
var numbers = new[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var digits = new[] { "zero", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem", "osiem", "dziewięć" };
var numbersName = from number in numbers
       select new { DigitName = digits[number], IsEven = (number % 2 == 0) };

foreach (var name in numbersName)
{
    Console.WriteLine("Liczba {0} jest liczbą " + (name.IsEven ? "parzystą" : "nieparzystą"), name.DigitName);
}
  1. Uruchom program za pomocą Debug -> Start Without Debugging (Ctrl+F4).
  2. Powinien uruchomić się program wyświetlający kolejne liczebniki, tak jak w ćwiczeniu poprzednim wraz z informacją o parzystości cyfry. Sytuacja ta została zilustrowana na Rys. 3.

Rys. 3. Liczebniki wraz z informacją o parzystości liczby.

Informacja
Typ anonimowy został zdeklarowany po słowie kluczowym select. Kompilator, na podstawie przypisanych wartości, wygenerował anonimową klasę, której obiekty będą przechowywały wyliczone dane.

Iloczyn kartezjański dwóch kolekcji

Korzystając z Select, możemy utworzyć iloczyn kartezjański. W tym ćwiczeniu tworzony jest iloczyn kartezjański dwóch zbiorów, ale wybrane zostaną tylko te pary, w których występuje zależność, że a < b.

  1. Zamień kod z poprzedniego zadania następującym kodem:
int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
int[] numbersB = { 1, 3, 5, 7, 8 };

var pairs =
    from a in numbersA
    from b in numbersB
    where a < b
    select new { a, b };
Console.WriteLine("Pary gdzie a < b:");
foreach (var pair in pairs)
{
    Console.WriteLine("{0} jest mniejsze niż {1}", pair.a, pair.b);
}
  1. Uruchom program za pomocą Debug -> Start Without Debugging (Ctrl+F4).
  2. Powinien uruchomić się program wyświetlający pary liczb. Pierwsza liczba, pochodząca z pierwszej tablicy (numbersA), jest mniejsza niż druga, która wywodzi się z drugiej tablicy (numbersB). Sytuacja została przedstawiona na Rys. 4.

Rys. 4. Pary liczb, w których pierwsza liczba jest mniejsza niż druga.

Podsumowanie

W tym artykule nauczyłeś się, jak utworzyć nową kolekcję przy użyciu Select, a także dowiedziałeś się o możliwości połączenia dwóch kolekcji. Ponadto, wykorzystałeś Select oraz typy anonimowe do utworzenia iloczynu kartezjańskiego.

W kolejnym artykule nauczymy się, jak wykonywać operacje na zbiorach.