Range | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar range

Listedeki Her X’inci Elemanı Çekmek

27 June 2013 1 yorum

Bu yazıda elimizdeki listenin her x’inci elemanını çeken extension method yazacağız.

Örneğin, bir ankete cevap veren katılımcılardan her 5000’inci katılımcıyı seçmek istediğimiz durumlarda böyle bir method’a ihtiyaç duyarız.

TakeEvery() extension method‘u, Language Integrated Query (LINQ) method’larından Skip() ve Take() gibi çalışacak, fakat listenin belli sayıda öğesini atlayıp, belli sayıda öğesini seçmek yerine, her x’inci elemanı seçecek.

İlk olarak TakeEverySample isimli projeyi oluşturalım;

IEnumerable<T> sınıfına TakeEvery() method’unu eklemek için projemize ExtensionMethods isimli sınıfı ekleyelim;

public static class ExtensionMethods
{
	public static IEnumerable<T> TakeEvery<T>(this IEnumerable<T> list, int every)
	{
		if (list == null)
		{
			throw new ArgumentException("list parametresi boş geçilemez");
		}
		if (every < 1)
		{
			throw new ArgumentException("'every' parametresi en az 1 olabilir");
		}

		var step = 0;

		var enumerator = list.GetEnumerator();
		while (enumerator.MoveNext())
		{
			step++;
			if (step == every)
			{
				yield return enumerator.Current;
				step = 0;
			}
		}
	}
}

İlk olarak method'a geçilen parametrelerin değerlerini kontrol ediyoruz, eğer uygun olmayan bir değer verilmişse ilgili mesaj ile bir hata fırlatıyoruz.

list parametresinin enumerator'unu GetEnumerator() method'u ile aldıktan sonra MoveNext() method'u ile liste üzerinde ilerliyoruz.

step değişkeni every değişkeninin değerine eşit olduğunda aradığımız kaydı bulmuşuzdur, ilgili kaydı geri döndürüyoruz.

Örnek kullanım;

var rakamlar = Enumerable.Range(1, 1000000);

var her50000 = rakamlar.TakeEvery(50000);

// her50000 = { 50000, 100000, 150000, 200000, 250000, 300000, ... }

C# ile iki tarih arasında belli bir günden kaç adet olduğunu bulmak

02 February 2013 Yorum yapılmamış

Geliştirdiğim projede iki tarih aralığında belirli bir günden kaç adet olduğunu bulmam gerekti.

Bunun için iki tarih arasındaki gün farkını alıp, bir tarih listesi oluşturmak için kullanıyorum, daha sonra tarih listesinin içinde istediğim gün’den kaç tane olduğunu sayıyorum.

Örneğin 2013 yılındaki Pazartesilerin adedi için;

var baslangic = new DateTime(2013, 1, 1);
var bitis = new DateTime(2013, 12, 31);
var toplamGun = (int)bitis.Subtract(baslangic).TotalDays + 1;

var tarihListe = Enumerable.Range(1, toplamGun).Select(e => baslangic.AddDays(e));

var gunAdet = tarihListe.Where(e => e.DayOfWeek == DayOfWeek.Monday).Count();

Euler – 7

17 October 2011 Yorum yapılmamış

Euler serisinin yedinci yazısında, Project Euler’in 7. sorusunu çözeceğiz;

Orjinal Soru; By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.

What is the 10.001st prime number?

Türkçesi; İlk altı asal sayı: 2, 3, 5, 7, 11, ve 13, altıncı asal asal sayının 13 olduğunu görürüz.

10.001nci asal sayı kaçtır?

Önce siz çözmeyi deneyin, çözemezseniz Devamını oku…

C# ile LINQ filtrelerinin üç farklı kullanımı (Predicate Function, Anonymous Method, Lambda Expression)

23 May 2011 Yorum yapılmamış

Listeler (IEnumerable<T> interface’ini implemente eden) üzerinde filtreleme yapmak için .Net 3.0’dan beri LINQ sorgularını kullanabiliyoruz.

LINQ ile gelen farklı operatör grupları sayesinde, listeler üzerinde sadece filtreleme yapmanın ötesinde bir kontrolümüz oluyor (daha detaylı bilgi için MSDN’de yeralan The .Net Standard Query Operators makalesini okuyabilirsiniz);

Bu yazımda, bir liste uzerinde LINQ sorgusu gerçekleştirmenin 3 farklı yolunu inceleyeceğiz;

  • Predicate
  • Anonymous Method
  • Lambda Sorgusu

Öncelikle üzerinde çalışacağımız bir listeye ihtiyacımız olacak, Enumerable sınıfının static Range method’u ile iki değer aralığındaki tam sayılardan oluşan listeyi kullanabiliriz;

Enumerable.Range(50, 100);

Predicate

private static bool CiftSayiKontrol(int Rakam)
{
	if (Rakam % 2 == 0)
		return true;
	else
		return false;
}

public static void Main(string[] args)
{
	var SonucListe = Enumerable.Range(1, 20).Where(CiftSayiKontrol);
	foreach (var Rakam in SonucListe)
	{
		Console.WriteLine(Rakam);
	}

	Console.ReadLine();
}

Sonuç;

LINQ Sorgusu - Predicate Function

Anonymous Method

public static void Main(string[] args)
{
	var SonucListe = Enumerable.Range(1, 20).Where(delegate(int number) {
		if (number % 2 == 0)
			return true;
		else
			return false;
	});

	foreach (var Rakam in SonucListe)
	{
		Console.WriteLine(Rakam);
	}

	Console.ReadLine();
}

LINQ Sorgusu - Anonymous Method

Lambda Sorgusu

public static void Main(string[] args)
{
	var SonucListe = Enumerable.Range(1, 20).Where(Rakam => Rakam % 2 == 0);
	foreach (var Rakam in SonucListe)
	{
		Console.WriteLine(Rakam);
	}

	Console.ReadLine();
}

LINQ Sorgusu - Lambda Expression

For – ForEach – List.ForEach performans karşılaştırması

31 October 2010 1 yorum

Bir dizinin tüm elemanları üzerinde bir aksiyon gerçekleştirmemiz gerektiğinde, sıklıkla şu üç yoldan birini kullanırız;

  • For döngüsü
  • ForEach Döngüsü
  • List generic sınıfının ForEach extension method’u

Şimdi basit bir örnek ile bu üç yöntemi karşılaştıralım (*);

(* Not : Karşılaştırmalar; Windows7 64bit kurulu, Core2Duo 3.0 GHz ve 4 GB Ram’li bilgisayarımda yapılmıştır. Sadece fikir verme amaçlıdır, farklı durumlarda faklı sonuçlar ile karşılaşılabilir.)

Öncelikle parametre olarak Generic List (List<T>) alan üç tane method yazalım;

private static long ToplamFor(List<int> Liste)
{
	long Sonuc = 0;
	int ListeAdet = Liste.Count;

	for (int iLoop = 0; iLoop < ListeAdet; iLoop++)
		Sonuc += Liste[iLoop];

	return Sonuc;
}

private static long ToplamForEach(List<int> Liste)
{
	long Sonuc = 0;

	foreach (int Rakam in Liste)
		Sonuc += Rakam;

	return Sonuc;
}

private static long ToplamForEachExtension(List<int> Liste)
{
	long Sonuc = 0;

	Liste.ForEach(Rakam => Sonuc += Rakam);

	return Sonuc;
}

Aynı testi 10 defa gerçekleştirip, ortalamasını alacak bir test fonksiyonu yazalım. Yazacağımız fonksiyonu test listesinde olacak eleman adedini parametre olarak alacak;

private static void Testler(int ListeElemanAdet)
{
	List<int> ForSureler = new List<int>();
	List<int> ForEachSureler = new List<int>();
	List<int> ForEachExtensionSureler = new List<int>();

	List<int> TestVerisi = Enumerable.Range(0, ListeElemanAdet).ToList();

	Stopwatch sw = new Stopwatch();

	for (int iLoop = 0; iLoop < 10; iLoop++)
	{
		sw.Restart();
		ToplamFor(TestVerisi);
		sw.Stop();
		ForSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEach(TestVerisi);
		sw.Stop();
		ForEachSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEachExtension(TestVerisi);
		sw.Stop();
		ForEachExtensionSureler.Add(sw.ElapsedTicks);
	}

	Console.WriteLine("For Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForSureler.Average());

	Console.WriteLine("ForEach Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForEachSureler.Average());

	Console.WriteLine("ForEach Extension ({0} Eleman) : {1}", ListeElemanAdet, ForEachExtensionSureler.Average());
}

Artık uygulamamızın test fonksiyonunu kullanacak son kod parçasını yazabiliriz;

public static void Main(string[] args)
{
	Console.WriteLine("Test Başladı");

	Testler(1000);
	Testler(5000);
	Testler(10000);
	Testler(50000);
	Testler(100000);
	Testler(500000);
	Testler(1000000);
	Testler(5000000);
	Testler(10000000);
	Testler(50000000);

	Console.WriteLine("Test Bitti");

	Console.ReadLine();
}

Bakalım yaptığımız testler nasıl sonuç vermiş;

For - ForEach - ForEach extension Performans Karşılaştırması / Ekran Görüntüsü

Sonuçlardan aşağıdaki tabloyu çıkarttım;

Test Verisi For ForEach ForEach Extension
1.000 71,1 121,5 79,7
5.000 34,3 92,2 55,6
10.000 70,0 185,1 110,4
50.000 349,3 918,4 568,3
100.000 715,2 1.902,7 1.159,0
500.000 3.583,3 9.379,3 5.600,0
1.000.000 7.260,4 18.877,9 11.242,8
5.000.000 37.927,2 96.096,9 57.845,4
10.000.000 74.553,5 192.621,6 115.559,6
50.000.000 371.698,1 956.394,4 572.776,7

İlk olarak 50.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000 elemana kadar inceleme

Son olarak 50.000.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000.000 elemana kadar inceleme