C# 8.0 – Ranges and Indices

Merhaba,

Yazılım dillerinde koleksiyonlar veya diziler üzerinde işlem yaparken ilgili yapıyı sadeleştirmek yahut verisel açıdan manüpüle edebilmek için LINQ sorgularından ya da her türlü tarafımızca veya harici geliştirilmiş algoritmalardan faydalanırız. C#, 8.0 versiyonunda koleksiyonel veri kaynakları üzerinde gerekli manipülasyonu sağlayabilmek ve bunun yanında kaynak içerisindeki tüm veriler üzerinde yapılan genel sorgulamalar ve algoritmalardan kaçınmak, yani direkt olarak hedef veri/ler odaklı çalışabilmek için yeni tipler ile operatörler geliştirmiş bulunmaktadır.

C# 8.0 ile gelen yeni tiplerimiz System.Index ile System.Range structerları iken, yeni işlevsel operatörlerimiz ise .. ile ^ ifadeleridir.

Şimdi gelin öncelikle yeni üretilen tipleri ele alarak ardından sırasıyla operatörleri inceleyelim.

System.Index

Dizi ve koleksiyon yapılarındaki index kavramının static tip olarak belirlenmiş halidir. Temelde index değerini tutmakla beraber ^ operatörüyle birlikte daha fazla bir anlam ifade etmekte ve dizinin index değerlerini tersine ifade edecek şekilde bir sorumluluk yüklenmektedir.

Şöyle ki;
C# 8.0 - Ranges and Indices
Yukarıdaki ekran görüntüsünde görüldüğü üzere “Index” structer tipinde tanımlanan “index” isimli “3” değerine sahip değişken “isimler” referansına sahip string dizisinin 3. index değerine tekabül etmektedir. Evet… Bu zaten bildiğimiz bir durumdur. Aşağıdaki görselde göz gezdirerek bir üstteki paragrafta bahsedilen ^ operatörü ile nasıl bir çalışma mantığında olduğunuda inceleyelim.

C# 8.0 - Ranges and Indices

Görüldüğü üzere index olarak tutulan sayısal değer ^ operatörü ile tersine bir index olarak tanımlanmıştır. Dolayısıyla bu şekilde tanımlanan bir ifade herhangi bir dizi yahut koleksiyonel bir değerde tersine indexe denk gelen datayı bizlere getirecektir. Burada dikkat edilmesi gereken nokta şudur ki; tersine index durumlarında index değerleri 0’dan değil 1’den başlamasıdır.

“Index” tipinin buradaki en büyük avantajı, tersine index durumunun sayısal olarak elimizde ifade edilmesini sağlamasıdır. Normal şartlarda herhangi bir sayısal değişkende bu değeri ifade etmemiz mümkün değildir.
C# 8.0 - Ranges and Indices

Index tipinin kullanımına dair aşağıdaki örneği inceleyebilirsiniz.

            string[] isimler = { "Hüseyin", "Hilmi", "Rıfkı", "Hatice", "Ayşe", "Mahmut", "Kazım", "Okan", "Emre", "Ali", "Naci", "Hüsnü", "Kamil" };

            Index i1 = ^3;
            Index i2 = 4;
            Console.WriteLine($"{isimler[i1]} - {isimler[i2]}");

C# 8.0 - Ranges and Indices

System.Range

Koleksiyonel veri üzerinde hangi değerler ile çalışacağımızı belirleyebilmek için index üzerinden aralık vermemizi ve bu bağıntıyı .. operatörü ile gerçekleştirmemizi sağlayan yapılanmanın kendine özgü türü Range yapısıdır.

C# 8.0 - Ranges and Indices

Yukarıdaki görseli incelerseniz eğer Range değişkeninin tuttuğu aralığın solundaki değer index bazlı bir göstergeye sahipken, sağındaki ise sıra numarasını ifade etmektedir. Dolayısıyla bu iki değerlere denk gelen verilerde dahil olmak üzere aralarındaki tüm veriler ilgili koleksiyonel değerde elde edilecektir. Örnek olarak görselin sonucu baz alınırsa; “Hatice”, “Ayşe”, “Mahmut” ve “Kazım” değerleri elde edilecektir.

C# 8.0 - Ranges and Indices
Yine bir üstteki görselde elde edilen sonucu tekrar elde edebilmek için yukarıdaki gibi bir çalışma gerçekleştirebiliriz. Burada dikkat edilmesi gereken nokta, .. operatörünün sağında ya da solunda ^ operatörü kullanılıyorsa sıra numarasına denk gelen ilgili değerin koleksiyona dahil olmadığıdır.

C# 8.0 - Ranges and Indices
Örneğin yukarıdaki görseldeki çalışmada; “Okan”, “Emre” ve “Ali” değerleri elde edilecektir.

Range tipine özel aşağıdaki örneği inceleyiniz;

            string[] isimler = { "Hüseyin", "Hilmi", "Rıfkı", "Hatice", "Ayşe", "Mahmut", "Kazım", "Okan", "Emre", "Ali", "Naci", "Hüsnü", "Kamil" };
            Range range = ^6..10;
            foreach (var item in isimler[range])
            {
                Console.WriteLine(item);
            }

C# 8.0 - Ranges and Indices

Buda bir ikinci örnek;

            string[] isimler = { "Hüseyin", "Hilmi", "Rıfkı", "Hatice", "Ayşe", "Mahmut", "Kazım", "Okan", "Emre", "Ali", "Naci", "Hüsnü", "Kamil" };

            Index i1 = 3;
            Index i2 = ^7;
            Range range = i1..i2;

            foreach (var item in isimler[range])
            {
                Console.WriteLine(item);
            }

C# 8.0 - Ranges and Indices

Vee son örnek;

            string[] isimler = { "Hüseyin", "Hilmi", "Rıfkı", "Hatice", "Ayşe", "Mahmut", "Kazım", "Okan", "Emre", "Ali", "Naci", "Hüsnü", "Kamil" };
            var list = isimler.ToList().GetRange(3, 4); //Eski usul
            var list2 = isimler.Skip(3).Take(4); //Eski usul
            Index i1 = 3;
            Index i2 = 7;
            Range range = i1..i2; //Yeni usul

            foreach (var item in isimler[range])
                Console.WriteLine(item);
            Console.WriteLine("************");
            foreach (var item in list)
                Console.WriteLine(item);
            Console.WriteLine("************");
            foreach (var item in list2)
                Console.WriteLine(item);

C# 8.0 - Ranges and Indices

Indexer[ ] içerisine tam sayı verilebildiği gibi Range yahut Index türüde verilebilir.

.. Operatörü

Koleksiyonel verilerde belirli aralığı temsil eden operatördür. Aralık operatörü diyede isimlendirebiliriz. Genellikle indexer[ ] operatörü içerisinde indexsel aralığı belirlemek için kullanılır.
C# 8.0 - Ranges and Indices
Yukarıdaki ekran alıntısında görüldüğü gibi sağına ve soluna sayısal bir değer alabildiği gibi özü itibariyle System.Index türünden de değerler alabilir ve geriye bir System.Range türünden yapı döndürür. Bu yapı kullanılarak ilgili değerlere karşılık gelen index aralıklarına giren tüm verilerin elde edilmesini sağlar.

Eskiden .. operatörü olmaksızın ihtiyaca dönük operasyonları hangi işlemlerle gerçekleştiriyorduk aradaki farkı görmek için aşağıdaki kod bloğunu inceleyiniz;

            string[] isimler = { "Hüseyin", "Hilmi", "Rıfkı", "Hatice", "Ayşe", "Mahmut", "Kazım", "Okan", "Emre", "Ali", "Naci", "Hüsnü", "Kamil" };
            var list = isimler.ToList().GetRange(3, 4); //Eski usul
            var list2 = isimler.Skip(3).Take(4); //Eski usul
            Index i1 = 3;
            Index i2 = 7;
            Range range = i1..i2; //Yeni usul

            foreach (var item in isimler[range])
                Console.WriteLine(item);
            Console.WriteLine("************");
            foreach (var item in list)
                Console.WriteLine(item);
            Console.WriteLine("************");
            foreach (var item in list2)
                Console.WriteLine(item);

Yerine geldiği genel kullanım operasyonlarına bakınca genellikle veri sayfalama vb. işlemlerde oldukça kullanışlı bir işleve sahip olduğu aşikardır.

^ Operatörü

Koleksiyonel yapılarda index değerinin tersini ifade eder. Normal index yapılanmasına nazaran ters index durumu 0’dan değil, 1’den başlamaktadır. Yani 10 elemanlı bir dizide; sonuncu eleman 9. indexe sahiptir lakin tersine operatörüyle “^0” değil “^1” değerine tekabül etmektedir.

C# 8.0 - Ranges and Indices
Görüldüğü üzere yanına yazılan ifade sayısal bir değer(tam sayı) olmak zorundadır. Sonuç olarak geriye bir System.Index türünden değer döndürür.

^ operatörü genellikle bir dizinin son elemanına erişmek için kullandığımız aşağıdaki karışık manevrasal algoritmadan bizleri kurtarmaktadır.
Eski stil;

            string isim = isimler[isimler.Length - 1];

Yeni stil;

            string isim = isimler[^1];

Son söz olarak;
Her yeni özellikte olduğu gibi bu özelliklerde biz yazılımcılar için daha kafiyeli kod yazmamıza olanak tanıyacaktır. Lakin tüm bu özellikler başlı başına bir anlam ifade ettiği için C# programlama dili okunabilirlik ve anlaşılabilirlik açısından oldukça zor bir hale bürünmektedir. Dili yeni öğrenenler daha temel mantıksal operatörleri oturtmakta zorlanırken, üsttüne üstlük temel yapıları ilgilendiren bu tarz yeni ve işlevsel açıdan ileri düzel operatörleri öğrenmeyi sonraki süreçlere(günlere/aylara ve hatta yıllara) bırakmalarını tavsiye ederim.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*

Copy Protected by Chetan's WP-Copyprotect.