Thread overview
İç içe yapılarda arama (find)
Apr 07, 2018
zafer
Apr 07, 2018
kerdemdemir
Apr 13, 2018
zafer
Apr 15, 2018
zafer
Apr 16, 2018
zafer
April 07, 2018

Merhaba Zafer Hocam,

Ben şöyle yaptım:

   auto sonuc3 = kitaplar.filter!( a => a.kitap.canFind!(a => a.isim == "Phyton 3 Veri Yapıları") ).map!(a => a.kitap.find!(a => a.isim == "Phyton 3 Veri Yapıları").front );
   listele(sonuc3.array);   // --> 3. Phyton 3 Veri Yapıları yazdırdı

Senin örneğinde bulmamasının sebebi arama yaptığın "kitaplar" dizisinde "k3" 'ün bulunmaması.
Ben önce k3 ' bulundurmayan kitap yapılarını eledim. Sonra ilk k3 örneği geri döndüm.

Bana senin değişik bir veri yapısına ihtiyaçın varmış gibi geldi. Örneğin k3 k2'i , k2'de k3'ü içerseydi Bu örnekte değilde başka örneklerde iş baya karışabilirdi. Acaba çizit veri yapısı gibi bir şey gerekiyor olabilirmi.
Şöyle birşeyler yapmıştım ben bir ara http://ddili.org/forum/thread/1737;?unb666sess=ae7b87bda5b3ef42f536ae78358a9178. Acaba kitap yapısı eşittir örnekteki Node sınıfı. Ve Graph'da bunların listesini içeren ve bu liste üstünde algoritmalar koşan sınıf şeklinde olsaydı senin problemine uyarmıydı.

Tam kodu aşağıda bulabilirsin.


import std.stdio: writefln;
import std.datetime: DateTime;
import std.algorithm;
import std.algorithm.searching;
import std.stdio;
import std.array;

struct Kitap
{
   int no;
   DateTime tarih;
   string isim;
   Kitap[] kitap;

   int opCmp(Kitap k) const
   {
       int sonuc = 0;
       if (tarih < k.tarih) sonuc = -1;
       if (tarih > k.tarih) sonuc = 1;
       return sonuc;
   }
}

void main()
{
   Kitap k3 = Kitap(3, DateTime(2018, 2, 22, 00, 00, 00), "Phyton 3 Veri Yapıları", null);
   Kitap k1 = Kitap(1, DateTime(2018, 2, 14, 00, 00, 00), "D Programlama Dili", null);
   Kitap k2 = Kitap(2, DateTime(2018, 2, 18, 00, 00, 00), "Her Yönüyle Python", [k3]);

   Kitap[] kitaplar = [k1, k2];

   auto sonuc1 = kitaplar.find!(a => a.isim == "Phyton 3 Veri Yapıları");
   listele(sonuc1);    // Bulamıyor!

   auto sonuc2 = kitaplar.find!(a => a.isim == "Her Yönüyle Python");
   listele(sonuc2);

   auto sonuc3 = kitaplar.filter!( a => a.kitap.canFind!(a => a.isim == "Phyton 3 Veri Yapıları") ).map!(a => a.kitap.find!(a => a.isim == "Phyton 3 Veri Yapıları").front );
   listele(sonuc3.array);   // --> 3. Phyton 3 Veri Yapıları yazdırdı
}

void listele(T)(T kitaplar)
{
   writefln("Sirali Kitap Listesi :");
   foreach (kitap; kitaplar.sort!((a, b) => a < b))
   {
       writefln("--> %d. %s", kitap.no, kitap.isim);
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 07, 2018

Merhaba,

Yapmaya çalıştığım iç içe geçmiş yapılar içinde find() ile arama yapmak. Birinci seviyede arama yapınca bir sorun çıkmadan arananı buluyor fakat ikinci seviyedeki kitabı bulamıyorum?

import std.stdio: writefln;
import std.datetime: DateTime;
import std.algorithm.sorting;
import std.algorithm.searching;

struct Kitap
{
   int no;
   DateTime tarih;
   string isim;
   Kitap[] kitap;

   int opCmp(Kitap k) const
   {
       int sonuc = 0;
       if (tarih < k.tarih) sonuc = -1;
       if (tarih > k.tarih) sonuc = 1;
       return sonuc;
   }
}

void main()
{
   Kitap k3 = Kitap(3, DateTime(2018, 2, 22, 00, 00, 00), "Phyton 3 Veri Yapıları", null);
   Kitap k1 = Kitap(1, DateTime(2018, 2, 14, 00, 00, 00), "D Programlama Dili", null);
   Kitap k2 = Kitap(2, DateTime(2018, 2, 18, 00, 00, 00), "Her Yönüyle Python", [k3]);

   Kitap[] kitaplar = [k1, k2];

   auto sonuc1 = kitaplar.find!(a => a.isim == "Phyton 3 Veri Yapıları");
   listele(sonuc1);    // Bulamıyor!

   auto sonuc2 = kitaplar.find!(a => a.isim == "Her Yönüyle Python");
   listele(sonuc2);
}

void listele(Kitap[] kitaplar)
{
   writefln("Sirali Kitap Listesi :");
   foreach (kitap; kitaplar.sort!((a, b) => a < b))
   {
       writefln("--> %d. %s", kitap.no, kitap.isim);
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2018

Öncelikle geç yanıtım için üzgünüm bu aralar işler oldukça yoğun ayrıca yardımın için teşekkürler Erdem.

Alıntı (kerdemdemir:1523101876):

>

Senin örneğinde bulmamasının sebebi arama yaptığın "kitaplar" dizisinde "k3" 'ün bulunmaması.

Aslında k3 bu dizi içinde mevcut ancak k2 yapısının içine yerleşmiş olarak bir iç seviyede bulunuyor. Kitaplar dizisini ekrana bastığımızda bunu görebiliriz.

Alıntı:

>

--> Kitaplar[] -> [Kitap(1, 2018-Feb-14 00:00:00, "D Programlama Dili", []), Kitap(2, 2018-Feb-18 00:00:00, "Her Yönüyle Python", [Kitap(3, 2018-Feb-22 00:00:00, "Phyton 3 Veri Yapıları", [])])]

Alıntı (kerdemdemir:1523101876):

>

Ben önce k3 ' bulundurmayan kitap yapılarını eledim. Sonra ilk k3 örneği geri döndüm.

Anladığım kadarıyla filter! metodu find! metodundan farklı olarak iç içe yerleşmiş yapılarda daha alt seviyede bulunan elemanlara ulaşabilme becerisine sahip. Oysa find! metodunun böyle bir becerisi bulunmuyor.

Sen ise filter! metodunun bu özelliğinden faydalanarak iç içe yerleşmiş yapılaradan oluşan dizinin tüm elemanlarını tek tek dolaşmaya başladın. Uğradığın her bir elemanın .isim özelliğine aradığın kelimeyi sordun ve olmayanları filter! sonucunda oluşacak listenin dışına attın.

Sonuçta elde ettiğin eleman veya duruma göre listedeki her eleman birinci seviye eleman olduğu için map! kullanarak hepsi üzerinde find! operasyonunu gerçekleştirdin. Gayet güzel bir çözüm olmuş. Oysaki find! bu işi kendi başına başarabilseydi çok daha pratik bir çözüme ulaşmak mümkün olacaktı.

Ayrıca işlemi sadeleştirmek adına sadece map! kullanarak yapmaya çalıştığımda şöyle bir sonuç ortaya çıkıyor.

--> Kitaplar[] -> [[], [Kitap(3, 2018-Feb-22 00:00:00, "Phyton 3 Veri Yapıları", [])]]

Burada boş olarak eklediği kayıt olmasa aslında bu çözümde işimi görüyor. Bu boş değerleri ek bir işlem yapmadan kaldırmak mümükün mü?

Alıntı (kerdemdemir:1523101876):

>

Bana senin değişik bir veri yapısına ihtiyaçın varmış gibi geldi.

Aslında buradaki veri yapısını e-ticaret sistelerinde kullanılan sınırsız kategori sistemini temsil etmek için oluşturmuştum. Amacım her kategori seçildiğinde ilgili alt kategorileri veritabanından almak yerine böyle bir yapı içinde arayıp bulmaktı. Özellikle find! metodunun bulunandan sonrasındaki tüm elemanları vermesi benim düşündüğüm sistem ile tam olarak örtüşüyordu. Bu gelişmelerden sonra belki ilgili bölümü tekrar yapılandırırım.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2018

Alıntı (zafer):

>

Oysa find! metodunun böyle bir becerisi bulunmuyor.

find'ın amacı, aranan elemanı bulmak. Döndürdüğü aralık, "bulunan eleman ve aralığın geri kalanı" anlamına geliyor. İstendiğinde arama tekrarlanabilir ve istediğin sonuç elde edilebilir.

"İstenmeyenler dışındakiler" diye düşününce filter doğru oluyor çünkü elemek anlamına geliyor.

Alıntı:

>

Ayrıca işlemi sadeleştirmek adına sadece map! kullanarak yapmaya çalıştığımda şöyle bir sonuç ortaya çıkıyor.

--> Kitaplar[] -> [[], [Kitap(3, 2018-Feb-22 00:00:00, "Phyton 3 Veri Yapıları", [])]]

Burada boş olarak eklediği kayıt olmasa

Doğru anlıyorsam, map, istenmeyen elemanla karşılaşınca boş eleman döndürüyor. Başka bir şey de yapamaz çünkü kesinlikle bir şey üretmesi gerekiyor. (Aslında yield kullanan bir generator olsa istenmeyenleri atlayabilir: http://ddili.org/ders/d/fiberler.html#ix_fiberler.Generator,%20std.concurrency )

Alıntı:

>

Bu boş değerleri ek bir işlem yapmadan kaldırmak mümükün mü?

O işin doğru çözümü filter. :) Önceden yaparsan map basitleşir, sonradan yaparsan map bir "geçersiz değer" döndürmek zorunda kalır ve o elemanların sonradan elenmeleri gerekir. O yüzden doğru çözüm filter. ;)

Alıntı:

>

find! metodunun bulunandan sonrasındaki tüm elemanları vermesi benim düşündüğüm sistem ile tam olarak örtüşüyordu. Bu gelişmelerden sonra belki ilgili bölümü tekrar yapılandırırım.

Bir de bağlantısını verdiğim Generator'ü dene. Arama adımları daha da karmaşık olunca istediğini kolayca atlayıp istediğini yield ile üretebilirsin.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 15, 2018

Alıntı (acehreli:1523638548):

>

find'ın amacı, aranan elemanı bulmak. Döndürdüğü aralık, "bulunan eleman ve aralığın geri kalanı" anlamına geliyor. İstendiğinde arama tekrarlanabilir ve istediğin sonuç elde edilebilir.

"İstenmeyenler dışındakiler" diye düşününce filter doğru oluyor çünkü elemek anlamına geliyor.

Sanırım burada bir yanlış anlama var :) Benim ilk sorumdaki amaç, topluluk içindeki belirli bir elemanı bulmaktı. Bunun için find! kullanmayı denedim ancak find! istedeğim sonucu vermedi. Çünkü aradığım eleman başka bir elemanın içinde yer alıyordu.

Buna istinaden "İstenmeyenler dışındakiler" düşüncesi Erdem'e ait bir düşünce :-) , bende bu düşüncenin nedenini araştırırken find! metodunun iç içe yerleşmiş elemanlar üzerinde arama yapamadığını gördüm.

Hatalı olabilirim ama benim öğrenmek istediğim find! iç içe yapılarda arama yapabilir mi? Ya da böyle bir arama için yukarıda Erdem'in örneklediği yöntem dışında bir yöntem var mı?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 16, 2018

Açıklama ve detaylı örnek için teşekkürler. Erdem ve senin örneklerin bana oldukça yardımcı oldu.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 16, 2018

Evet, yanlış anlamışım. :) Hayır, find'ın böyle bir yeteneği yok (zaten hangi üyeyle ilgilendiğimizi kendisi bilemezdi). Erdem'in yaptığına benzer biçimde, map ve joiner yardımıyla iç içe elemanlar tek aralık gibi sunulabilir ve find o tek aralık üzerinde işletilebilir:

import std.stdio;
import std.algorithm;
import std.range;

struct A {
   int a;
}

struct B {
   A[] alar;
}

struct C {
   B[] bler;
}

void main() {
   auto cler = [ C([B([A(10), A(11)]),
                    B([A(20), A(21)])]),
                 C([B([A(30), A(31)]),
                    B([A(40), A(41)])]) ];

   auto butunAlar = cler.map!(c => c.bler).joiner.map!(b => b.alar).joiner;
   writeln(butunAlar);
   auto bulunan = butunAlar.find!(a => a.a == 30);
   if (!bulunan.empty) {
       writeln("Buldum: ", bulunan.front);
   } else {
       writeln("Bulamadım");
   }
}

30 değerini arıyor:
'
[A(10), A(11), A(20), A(21), A(30), A(31), A(40), A(41)]
Buldum: A(30)
'
Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 16, 2018

Kodu ilk koda benzettim: Şimdi her C içinde bir de C dilimi var. Biraz da açıklama ekledim:

import std.stdio;
import std.algorithm;
import std.range;

struct A {
   int a;
}

struct B {
   A[] alar;
}

struct C {
   B[] bler;
   C[] cler;
}

void main() {
   auto cler = [ C([B([A(10), A(11)]),
                    B([A(20), A(21)])],
                   [C([B([A(25), A(26)])])]),
                 C([B([A(30), A(31)]),
                    B([A(40), A(41)])],
                   [C([B([A(45), A(46)])])]) ];

   auto butunAlar =
       // Bütün C'ler ile başlıyoruz:
       cler
       // Her C'yi ve içerdiği C'leri art arda getiriyoruz
       .map!(c => chain(c.only, c.cler))
       // Art arda gelen farklı türdeki aralıkların elemanlarını tek aralık gibi gösteriyoruz:
       .joiner
       // Her C'nin bler elemanları ile ilgileniyoruz:
       .map!(c => c.bler)
       // Aynı biçimde, elemanları B olan bir aralığa dönüştürüyoruz:
       .joiner
       // Her B'nin alar elemanları ile ilgileniyoruz:
       .map!(b => b.alar)
       // Aynı biçimde, elemanları A olan bir aralığa dönüştürüyoruz:
       .joiner;

   writeln(butunAlar);
   auto bulunan = butunAlar.find!(a => a.a == 30);
   if (!bulunan.empty) {
       writeln("Buldum: ", bulunan.front);
   } else {
       writeln("Bulamadım");
   }
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]