Yazılım.
CevapSitesi.com Beta!
Çözüm Noktası
Facebook, Twitter, Google+ veya e-posta ile paylaşın.
| Sorular | Makaleler | Üyeler | Etiketler  | İletişim
Soru sormak ya da cevap vermek için;
giriş yapın veya üye olun.

Sosyal medya hesaplarınızla da giriş yapabilirsiniz.
0

LINQ - Gruplama (Grouping) Örnekleri

Bu makalede kullanılan veri kaynağını görmek için tıklayın.

GroupBy yöntemi ve group ... by ... into ... cümleciği listedeki elemanları verilen anahtar alana göre (örneğin öğrencileri sınıf bilgilerine göre) gruplayarak oluşturulan gruplar üzerinde işlem yapmamıza imkan sağlar. Gruplandırmada kullanılan alana GrupAdi.Key şeklide ulaşılabilir.

Basit GroupBy Örneği 1

Bu örnek öğrenci bilgilerinden oluşan bir veri kaynağındaki kayıtları sınıflarına göre gruplandırır ve sınıf gruplarındaki anahtar alan (sınıf alanı) ve sınıf gruplarındaki kayıt sayısı bilgileri ile isimsiz tip oluşturup seçer. Daha sonra bu tiplerden oluşturduğu listeyi çıktıya yazar.
var Ogrenciler = OgrencileriGetir();

var Siniflar = from Ogrenci in Ogrenciler
               orderby Ogrenci.Sinif 
               group Ogrenci by Ogrenci.Sinif into Sinifi
               select new { Sinif = Sinifi.Key, OgrenciSayisi = Sinifi.Count() };

Console.WriteLine("Sınıf öğrenci sayıları :");

foreach (var Satir in Siniflar)
{
    Console.WriteLine("{0}. sınıfta {1} öğrenci var.", Satir.Sinif, Satir.OgrenciSayisi);
}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Sınıf öğrenci sayıları :
1. sınıfta 3 öğrenci var.
2. sınıfta 5 öğrenci var.
3. sınıfta 5 öğrenci var.
4. sınıfta 4 öğrenci var.

Aynı örnek, LINQ Yöntem Sözdizimi (LINQ Method Syntax) ile şu şekilde yazılabilir:

var Ogrenciler = OgrencileriGetir();

var Siniflar =
               Ogrenciler.OrderBy(Ogrenci => Ogrenci.Sinif)
                         .GroupBy(Ogrenci => Ogrenci.Sinif)
                         .Select(Sinif => new { Sinif = Sinif.Key, OgrenciSayisi = Sinif.Count() });

Console.WriteLine("Sınıf öğrenci sayıları :");

foreach (var Satir in Siniflar)
{
    Console.WriteLine("{0}. sınıfta {1} öğrenci var.", Satir.Sinif, Satir.OgrenciSayisi);
}
Console.ReadLine();

Basit GroupBy Örneği 2

Bu örnek öğrenci bilgilerinden oluşan bir veri kaynağındaki kayıtları sıraladıktan sonra (gruplamanın daha hızlı yapılmasına yardımcı olabilir) sınıflarına göre gruplandırır, bu grupları seçerek ve sınıf gruplarından yeni bir grup listesi oluşturur. Daha sonra iç içe foreach döngüleri ile dıştaki foreach döngüsünde grupların anahtar alanlarını ve içerdeki foreach döngüsünde gruplardaki öğrencileri çıktıya yazar.
var Ogrenciler = OgrencileriGetir();

var Siniflar = from Ogrenci in Ogrenciler
               orderby Ogrenci.Sinif
               group Ogrenci by Ogrenci.Sinif into SinifGrubu
               select SinifGrubu;

Console.WriteLine("Sınıflardaki öğrenciler...");

foreach (var BirSiniftakiler in Siniflar)
{

    Console.WriteLine("{0}. sınıftaki öğrenciler :", BirSiniftakiler.Key);

    foreach (var Ogrenci in BirSiniftakiler)
    {
        Console.WriteLine("{0} {1}", Ogrenci.Adi, Ogrenci.Soyadi);
    }
}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Sınıflardaki öğrenciler...
1. sınıftaki öğrenciler :
Tekin Uğurlu
Kenan Oran
Erhan Erkanlı
2. sınıftaki öğrenciler :
Ahmet Geçe
Hale Birinci
Ayşe Hanım
Nuri Babayiğit
Erhan Fidan
3. sınıftaki öğrenciler :
Jale İkinci
Fatma Teyze
Cevdet Döğer
Lale Üçüncü
Erhan Çelik
4. sınıftaki öğrenciler :
Tuncay Çağrı
Mesut Bahtiyar
Veli Canlı
Mehmet Emre

Aynı örnek, LINQ Yöntem Sözdizimi (LINQ Method Syntax) ile şu şekilde yazılabilir:

var Ogrenciler = OgrencileriGetir();

var Siniflar = Ogrenciler.OrderBy(Ogrenci => Ogrenci.Sinif).GroupBy(Ogrenci => Ogrenci.Sinif);

Console.WriteLine("Sınıflardaki öğrenciler...");

foreach (var BirSiniftakiler in Siniflar)
{

    Console.WriteLine("{0}. sınıftaki öğrenciler :", BirSiniftakiler.Key);

    foreach (var Ogrenci in BirSiniftakiler)
    {
        Console.WriteLine("{0} {1}", Ogrenci.Adi, Ogrenci.Soyadi);
    }
}
Console.ReadLine();

Basit GroupBy Örneği 3

Bu örnek öğrenci bilgilerinden oluşan bir veri kaynağındaki kayıtları başarı durumuna göre gruplandırır (Ogrenci.Ortalama >= 55  işleminin sonucu "true" ve "false" olanları iki grup şeklinde), bu grupları seçerek başarı gruplarından yeni bir grup listesi oluşturur. Daha sonra iç içe foreach döngüleri ile dıştaki foreach döngüsünde grupların anahtar alanlarına bakarak belirlediği bir değeri (örnekte "başarılı" ve "başarısız" metinlerini) ve içerdeki foreach döngüsünde gruplardaki öğrencileri çıktıya yazar.
var Ogrenciler = OgrencileriGetir();

var Siniflar = from Ogrenci in Ogrenciler
               orderby Ogrenci.Sinif
               group Ogrenci by Ogrenci.Ortalama >= 55 into BasariGrubu
               select BasariGrubu;

Console.WriteLine("Öğrencilerin Başarı Durumları...");

foreach (var BasariGrubu in Siniflar)
{

    Console.WriteLine("\n- {0} öğrenciler :", BasariGrubu.Key ? "Başarılı" : "Başarısız");

    foreach (var Ogrenci in BasariGrubu)
    {
        Console.WriteLine("{0} {1} -> {2:0.00}", Ogrenci.Adi, Ogrenci.Soyadi, Ogrenci.Ortalama);
    }

}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Öğrencilerin Başarı Durumları...

- Başarısız öğrenciler :
Tekin Uğurlu -> 30,00
Hale Birinci -> 25,00
Cevdet Döğer -> 16,25
Lale Üçüncü -> 16,67
Mesut Bahtiyar -> 36,67
Veli Canlı -> 43,33

- Başarılı öğrenciler :
Kenan Oran -> 66,67
Erhan Erkanlı -> 90,00
Ahmet Geçe -> 76,67
Ayşe Hanım -> 80,00
Nuri Babayiğit -> 65,00
Erhan Fidan -> 86,25
Jale İkinci -> 97,00
Fatma Teyze -> 89,25
Erhan Çelik -> 78,33
Tuncay Çağrı -> 73,33
Mehmet Emre -> 66,33

Aynı örnek, LINQ Yöntem Sözdizimi (LINQ Method Syntax) ile şu şekilde yazılabilir:

var Ogrenciler = OgrencileriGetir();

var Siniflar = Ogrenciler.GroupBy(Ogrenci => Ogrenci.Ortalama >= 55);

Console.WriteLine("Öğrencilerin Başarı Durumları...");

foreach (var BasariGrubu in Siniflar)
{

    Console.WriteLine("\n- {0} öğrenciler :", BasariGrubu.Key ? "Başarılı" : "Başarısız");

    foreach (var Ogrenci in BasariGrubu)
    {
        Console.WriteLine("{0} {1} -> {2:0.00}", Ogrenci.Adi, Ogrenci.Soyadi, Ogrenci.Ortalama);
    }

}
Console.ReadLine();

Yuvalanmış (Nested) GroupBy Örneği

Bu örnek öğrenci bilgilerinden oluşan bir veri kaynağındaki kayıtları sınıflarına göre gruplandırır. Oluşturduğu sınıf gruplarının anahtarları (sınıf bilgisi) ve sınıf grubu içinde ikinci bir gruplandırma ile öğrencileri cinsiyetine göre ayırdığı bir alt gruplandırma ile oluşturduğu isimsiz tipleri seçer. Oluşan grup listesindeki grupları ve gruplardaki öğrencilerin numara ad ve soyadlarını iç içe foreach döngüleri kullanarak çıktıya yazar.
var Ogrenciler = OgrencileriGetir();

var CinsiyeteGoreSinifListeleri = 
        from Ogrenci in Ogrenciler
        orderby Ogrenci.No
        group Ogrenci by Ogrenci.Sinif into SinifGrubu
        select new
        {
            SinifNo = SinifGrubu.Key,
            SinifOgrencileri = from BuSiniftakiOgrenci in SinifGrubu
                               orderby BuSiniftakiOgrenci.Cinsiyet
                               group BuSiniftakiOgrenci by BuSiniftakiOgrenci.Cinsiyet into SinifCinsiyetGrubu
                               select SinifCinsiyetGrubu
        };

Console.WriteLine("Cinsiyete Göre Gruplanmış Sınıf Öğrenci Listeleri...");

foreach (var Sinif in CinsiyeteGoreSinifListeleri)
{

    Console.WriteLine("\n{0}. sınıf öğrencileri :", Sinif.SinifNo);

    foreach (var OgrenciGrubu in Sinif.SinifOgrencileri)
    {
        Console.WriteLine("{0} öğrenciler:", OgrenciGrubu.Key);
        foreach (var Ogrenci in OgrenciGrubu)
        {
            Console.WriteLine("{0} - {1} {2}",
                              Ogrenci.No,
                              Ogrenci.Adi,
                              Ogrenci.Soyadi);
        }
    }
}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Cinsiyete Göre Gruplanmış Sınıf Öğrenci Listeleri...

2. sınıf öğrencileri :
Bayan öğrenciler:
3 - Hale Birinci
13 - Ayşe Hanım
Erkek öğrenciler:
1 - Nuri Babayiğit
6 - Ahmet Geçe
16 - Erhan Fidan

4. sınıf öğrencileri :
Erkek öğrenciler:
2 - Tuncay Çağrı
8 - Mesut Bahtiyar
12 - Veli Canlı
14 - Mehmet Emre

3. sınıf öğrencileri :
Bayan öğrenciler:
4 - Jale İkinci
9 - Lale Üçüncü
15 - Fatma Teyze
Erkek öğrenciler:
11 - Cevdet Döğer
17 - Erhan Çelik

1. sınıf öğrencileri :
Erkek öğrenciler:
5 - Kenan Oran
7 - Tekin Uğurlu
10 - Erhan Erkanlı

Aynı örnek, LINQ Yöntem Sözdizimi (LINQ Method Syntax) ile şu şekilde yazılabilir:

var Ogrenciler = OgrencileriGetir();

var CinsiyeteGoreSinifListeleri =
          Ogrenciler.OrderBy(Ogrenci => Ogrenci.No)
                    .GroupBy(Ogrenci => Ogrenci.Sinif)
                    .Select(SinifGrubu =>
                        new
                        {
                            SinifNo = SinifGrubu.Key,
                            SinifOgrencileri =
                                  SinifGrubu.OrderBy(BuSiniftakiOgrenci => BuSiniftakiOgrenci.Cinsiyet)
                                            .GroupBy(BuSiniftakiOgrenci => BuSiniftakiOgrenci.Cinsiyet)
                        });

Console.WriteLine("Cinsiyete Göre Gruplanmış Sınıf Öğrenci Listeleri...");

foreach (var Sinif in CinsiyeteGoreSinifListeleri)
{

    Console.WriteLine("\n{0}. sınıf öğrencileri :", Sinif.SinifNo);

    foreach (var OgrenciGrubu in Sinif.SinifOgrencileri)
    {
        Console.WriteLine("{0} öğrenciler:", OgrenciGrubu.Key);
        foreach (var Ogrenci in OgrenciGrubu)
        {
            Console.WriteLine("{0} - {1} {2}",
                              Ogrenci.No,
                              Ogrenci.Adi,
                              Ogrenci.Soyadi);
        }
    }
}
Console.ReadLine();

Karşılaştırıcı Kullanan GroupBy Örnekleri :

GroupBy, bir karşılaştırıcı ile kullanılabilir. Karşılaştırıcı, IEqualityComparer arayüzünü uygulayan, Equals ve GetHashCode isimli iki metoda sahip bir sınıftır.IEqualityComparer 'in Equals yöntemi, grupları birbirinden ayıracak, gelen iki parametrenin eşit olup olmadığını döndüren bir yöntemdir. Biz örneğimizde hem cinsiyeti, hem de başarı durumu farklı olanların farklı gruplar olduğunu bildiren bir kod yazdık. IEqualityComparer'in GetHashCode  yöntemi ise, verileri birbirinden ayırmak için kullanılacak HashCode adı verilen bir kod üretir. Bu kodun hangi verilerden üretileceğini bu yöntem içinde biz belirtiriz. GroupBy da kayıtları birbirinden ayırmak için bu yöntemi çağırır. HashCode, sınıfların birbirinden ayıracak özel bir sayıdır (32 bit bir tamsayıdır). Sınıfların GetHashCode yöntemi ile elde edilebilir. Bu kod özel bir algoritma ile üretilir ve verileri karşılaştırmada kullanılır ancak her sınıfın HasCode değerinin farklı olacağının bir garantisi yoktur.

Karşılaştırıcı Kullanarak GroupBy Örneği

Bu örnek öğrenci bilgilerinden oluşan bir veri kaynağındaki kayıtları karşılaştırıcı sınıfı kullanarak başarı durumları ve cinsiyetlerine göre gruplandırır (Başarılı erkekler, başarısız erkekler, başarılı bayanlar ve başarısız bayanlar). İç içe 2 döngü kullanarak grupların bilgilerini ve gruplardaki öğrencilerin ad, soyad ve ortalama bilgilerini çıktıya yazar.
var Ogrenciler = OgrencileriGetir();

var CinsiyeteGoreBasariListesi = Ogrenciler.GroupBy(Ogrenci => Ogrenci, new CinsiyeteGoreBasariKarsilastirici());

Console.WriteLine("Cinsiyete göre başarı durumları listesi...");

foreach (var OgrenciGrubu in CinsiyeteGoreBasariListesi)
{

    Console.WriteLine("\n{0} {1} :",
                      OgrenciGrubu.Key.Basarili ? "Başarılı" : "Başarısız",
                      OgrenciGrubu.Key.Cinsiyet == "Erkek" ? "erkekler" : "bayanlar");
    foreach (var Ogrenci in OgrenciGrubu)
    {
        Console.WriteLine("{0} {1}. Ortalaması {2:0.00}",
                          Ogrenci.Adi, Ogrenci.Soyadi, Ogrenci.Ortalama);
    }
}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Cinsiyete göre başarı durumları listesi...

Başarılı erkekler :
Tuncay Çağrı. Ortalaması 73,33
Ahmet Geçe. Ortalaması 76,67
Mehmet Emre. Ortalaması 66,33
Nuri Babayiğit. Ortalaması 65,00
Kenan Oran. Ortalaması 66,67
Erhan Erkanlı. Ortalaması 90,00
Erhan Fidan. Ortalaması 86,25
Erhan Çelik. Ortalaması 78,33

Başarılı bayanlar :
Jale İkinci. Ortalaması 97,00
Fatma Teyze. Ortalaması 89,25
Ayşe Hanım. Ortalaması 80,00

Başarısız erkekler :
Tekin Uğurlu. Ortalaması 30,00
Mesut Bahtiyar. Ortalaması 36,67
Veli Canlı. Ortalaması 43,33
Cevdet Döğer. Ortalaması 16,25

Başarısız bayanlar :
Hale Birinci. Ortalaması 25,00
Lale Üçüncü. Ortalaması 16,67

Örnekte kullanılan karşılaştırıcı sınıf şöyledir :

public class CinsiyeteGoreBasariKarsilastirici : IEqualityComparer
{

    public bool Equals(Kayit x, Kayit y)
    {

        if (x.Cinsiyet != y.Cinsiyet && x.Basarili != y.Basarili) return false;

        return true;

    }

    public int GetHashCode(Kayit Ogrenci)
    {

        return Ogrenci.Basarili.GetHashCode() + Ogrenci.Cinsiyet.GetHashCode();

    }

}

Karşılaştırıcı Kullanarak Haritalanmış (Mapped) GroupBy Örneği

Örneğimiz, bir dizideki anagramları (aynı harflerle yazılan kelimeler) bulmaktadır. Karşılaştırıcı sınıfta kelimelerin anagram olup olmadıklarını belirleyen "SiraliKarakterleriVer" isimli özel bir yöntem kullanıldı. Bu yöntem parametre olarak verilen kelimedeki harfleri alfabetik sıraya sokmaktadır. Anagram kelimelerin harflerinin alfabetik sırası aynı olacağından bu yöntem sayesinde anagram kelimeler karşılaştırılabilmektedir.

Bu örnek dizideki anagramları bulur ve gruplandırır. Daha sonra bu anagram gruplarını çıktıya yazar.

string[] Anagramlar = { "şart", "yumak", "antik", "traş", "yamuk", "nakit" };

var AnagramGruplari = Anagramlar.GroupBy(Kelime => Kelime, new AnagramEsitlikKarsilastirici());

Console.WriteLine("Dizideki anagramlar :");
foreach (var Grup in AnagramGruplari)
{
    Console.WriteLine("---");
    foreach (var Kelime in Grup)
    {
        Console.WriteLine(Kelime);
    }
}
Console.ReadLine();

Örneğin çıktısı şöyle olacaktır :

Dizideki anagramlar :
---
şart
traş
---
yumak
yamuk
---
antik
nakit

Dizide kullanılan karşılaştırıcı sınıf şöyledir:

public class AnagramEsitlikKarsilastirici : IEqualityComparer
{
    public bool Equals(string x, string y)
    {
        return SiraliKarakterleriVer(x) == SiraliKarakterleriVer(y);
    }

    public int GetHashCode(string obj)
    {
        return SiraliKarakterleriVer(obj).GetHashCode();
    }

    private string SiraliKarakterleriVer(string Kelime)
    {
        char[] KelimeninKarakterleri = Kelime.ToCharArray();
        Array.Sort(KelimeninKarakterleri);
        return new string(KelimeninKarakterleri);
    }
}

Kaynak:
https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b



Diğer LINQ Makaleleri:


Yazan: 10.04.16 22:14
canora
101,384p 4ü