Merhaba,
Aşağıda, anonim işlevler (lambdas, function literals) ve özellikle tek başlarına çok anlam ifade etmediklerinden, eşlemleme (map) ve ergitme (reduce) ifadeleri ile birlikte yer alan sıralı işlem örnekleri var...
La Lambada - lambda, ifade, işlem - eşlem, erime - ergime ?!¡¿ what, onlar da ne 😉
Durun durun, hemen kafanız karışmasın anlatcam :)
import std.algorithm, std.range, std.stdio;
void main()
{
auto karesiniAl = (int a) => a * a;
auto geleniTopla = (int a, int b) => a + b;
auto aralık = 1.ir(16); /*
int[] aralık = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];//*/
[1,2,3,4].map!karesiniAl
.reduce!geleniTopla
.writeln; // "30" = 1² + 2² + 3² + 4²
// aynın şeyleri tekrarlamayalım:
auto hesapla(R)(R range) {
return range.map!karesiniAl
.reduce!geleniTopla;
}
hesapla(aralık).writeln; /* "1496" = aşağıdaki
4 parçanın toplamı (30 + 174 + 446 + 846) */
auto parçala = aralık.chunks(4);
parçala.each!(parça => hesapla(parça).writeln);
}
/*
Öncelikle, Ali hocanın yazdığı ir(inclusiveRange) olanağınız yoksa ir yerine iota yazıp son parametereyi 1 arttırın ya da satırın başına // işareti koyarsanız o satır görünmez olur ve altındaki dizi açılır; aralık değildir ama çalışır.*/
Birbirine bağlı örnekler ürkütmesin! Burda, topu topu 2-3 temel konu var ama dilerseniz kendiniz deneyip hem örnek sayısını arttırabilir hem de daha iyi anlayabilirsiniz.
Girişte kullandığım ifadelere gelince. Tabii ki şu an dinlediğim şarkı olan La Lambada ile konumuzun hiçbir alakası yok, sadece isim benzerliği ve espri 😀
Anonim işlevleri (lambda), dilerseniz isim vermeden ve doğrudan map!(...) & reduce!(...)
ile tek tek kullanabilirsiniz. Şimdi bir elinizde bir takım işlemler var yani işlevler (lambdas) peki bir işe yarıyor mu?
Yok! (Tıpkı su olmadan tek elinizde sabun ile temizlik yapamamanız gibi...)
Şimdi, diğer elinize eşlemi (map) alıyorsunuz, yani veriyi (örnekteki 1-16 sayı aralığını) ve her parçanın bir kopyasını alıp eşlemleme yapıyorsunuz. Her seferinde, ilgili yordam (lambda) işletilmesinin neticesi "işlem sonucu" üretilir ve bu, sırada göreceğimiz konu olan reduce'daki, gibi başa geri döndürülmeyip bir sonraki veriye geçer. Peki yeter mi?
Yetmez...
Çünkü biz bu sonucu bir döngü içinde, bir sayıyı hafızada teker teker yuvarlayarak da yapabilirdik. Peki farklı her sonucu (sayıyı) topraktaki madenler gibi düşünürsek durum nasıl olurdu?
Yani topraktaki herşeyi (kodlamada sayıları) ısıtıp eriterek (reducing) tıpkı maden filizleri/kristalleri bir araya gelip 30 numaralı madeni (kodlamada ekrana ilk yazdığımız sonuç) elde etmek istiyorsak ne yapıyoruz:
Ergitme (reduce), burada ergiten işlev ona gelen her iki sayıyı topluyor ve lambda görevini yaptıktan sonra reduce(), sonucu başa döndürüp bir sonraki veriyle birlikte işleme devam ediyor. Devamı daha da tatlı!
Farkındaysanız sonra yine benzer bir örneği yapıyoruz. Veriyi chunks() ile parçalara bölüp tekrar olmaması için her birini (4x4) hesapla() işlevinden geçirirsek (burda foreach ile de yapabileceğimiz each'den faydalandık) bu sefer daha faydalı bir örnek yapmış oluruz.
Başarılar...