Koleksiyonları sorgulamanın zarif yolu: Where, Select, OrderBy, Average, Max, GroupBy ve lambda ifadeleri, ölçüm verisi üzerinde.
LINQ nedir?
LINQ (Language Integrated Query, "dile gömülü sorgu") listeler, diziler ve veritabanları gibi veri kaynakları üzerinde filtreleme, sıralama, dönüştürme ve özetleme yapmanı sağlayan metot ailesidir. Elle for döngüsü ve geçici değişkenlerle yazdığın işleri tek satırda söylersin. Kullanmak için using System.Linq; gerekir; yeni .NET projelerinde bu zaten otomatik eklidir.
Lambda ifadesi
LINQ'in dili lambda'lardır. x => x > 22, "x verilirse x'in 22'den büyük olup olmadığını söyle" anlamına gelen küçük bir adsız metottur. Ok işaretinin solunda parametre, sağında sonuç yer alır.
Where: filtrele
double[] sicakliklar = { 21.5, 22.1, 20.9, 23.4, 22.8, 35.2, 19.8 };
var sicaklar = sicakliklar.Where(t => t > 22);
foreach (var t in sicaklar)
Console.WriteLine(t);
Console.WriteLine($"Adet: {sicaklar.Count()}");
22,1
23,4
22,8
35,2
Adet: 4
Select: dönüştür
Her elemanı başka bir şeye çevirir. Celsius'tan Fahrenheit'a:
var fahrenheit = sicakliklar
.Select(c => c * 9 / 5 + 32)
.Take(3); // yalnızca ilk 3
foreach (var f in fahrenheit)
Console.WriteLine($"{f:F1} °F");
70,7 °F
71,8 °F
69,6 °F
OrderBy ve toplulaştırma metotları
Console.WriteLine(string.Join(", ", sicakliklar.OrderBy(t => t)));
Console.WriteLine($"Ortalama: {sicakliklar.Average():F2}");
Console.WriteLine($"En yüksek: {sicakliklar.Max()}");
Console.WriteLine($"En düşük: {sicakliklar.Min()}");
Console.WriteLine($"Toplam: {sicakliklar.Sum():F1}");
19,8, 20,9, 21,5, 22,1, 22,8, 23,4, 35,2
Ortalama: 23,67
En yüksek: 35,2
En düşük: 19,8
Toplam: 165,7
OrderByDescending büyükten küçüğe sıralar. Ortalama: 165,7 / 7 = 23,67.
Zincirleme
LINQ'in güzelliği, metotları birbirine bağlayabilmendir. "22 dereceden sıcak olan ölçümleri bul, büyükten küçüğe diz, ilk ikisini al":
var en = sicakliklar
.Where(t => t > 22)
.OrderByDescending(t => t)
.Take(2)
.ToList();
Console.WriteLine(string.Join(" ve ", en));
35,2 ve 23,4
ToList() sorgu sonucunu gerçek bir listeye çevirir. Not: LINQ sorguları tembel çalışır; sonucu bir foreach, ToList(), Count() gibi bir şey istemeden hesaplanmaz.
Any, All, First, FirstOrDefault
Console.WriteLine(sicakliklar.Any(t => t > 30)); // True: 30'dan büyük var mı?
Console.WriteLine(sicakliklar.All(t => t > 15)); // True: hepsi 15'ten büyük mü?
double ilkSicak = sicakliklar.First(t => t > 22); // 22,1; bulamazsa HATA verir
double yok = sicakliklar.FirstOrDefault(t => t > 100); // bulamazsa varsayılan: 0
Console.WriteLine(ilkSicak);
Console.WriteLine(yok);
True
True
22,1
0
Eleman bulunamayabilecekse First yerine FirstOrDefault kullan; ona uygun varsayılan değer döner.
Nesne listelerinde ve GroupBy
var olcumler = new List<Olcum>
{
new("K1", 10), new("K2", 20), new("K1", 30), new("K2", 40), new("K3", 50)
};
var gruplar = olcumler.GroupBy(o => o.Kanal);
foreach (var g in gruplar)
{
Console.WriteLine($"{g.Key}: {g.Count()} ölçüm, ortalama {g.Average(o => o.Deger):F1}");
}
record Olcum(string Kanal, double Deger);
K1: 2 ölçüm, ortalama 20,0
K2: 2 ölçüm, ortalama 30,0
K3: 1 ölçüm, ortalama 50,0
GroupBy elemanları verilen anahtara göre gruplar; her grubun Key özelliği anahtarı verir. record tanımının dosyanın sonuna konduğuna dikkat et (üst düzey ifadelerden sonra).
İpucu: Önce basit bir foreach ile yaz, çalıştığından emin ol, sonra LINQ'a çevir. Okunaklı olmayan uzun LINQ zincirlerini birkaç değişkene böl.
Dikkat: Boş koleksiyonda Average(), Max(), First() hata fırlatır. Boş olma ihtimali varsa önce Any() ile kontrol et.
Kendin dene
Bir List<int> oluştur: not listesi gibi 10 değer. LINQ ile (1) ortalamanın üstündekileri bul, (2) 60 ve üzeri geçenlerin sayısını yaz, (3) en yüksek üç notu büyükten küçüğe listele. Her birini önce foreach ile yapıp sonra LINQ ile yaz ve karşılaştır.
// Mini sınav
Bir seçeneğe tıkla; doğru mu yanlış mı, anında ve nedeniyle birlikte göreceksin.
Bitirdiğinde işaretle: ilerlemen kaydolur, +20 XP kazanırsın.
İpucu: ← → tuşlarıyla dersler arasında gezinebilirsin.