Forum: Projeler Genel RSS
Tree of Categories
Bağlı liste gibi bir yapı...
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1913 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Tree of Categories
Merhabalar,

Aslında konu Kelimatik projesi ile ilgili ama genel bir konu olduğu için ve herkesin projesinde faydalı olabileceğinden izninizle burada tartışalım. Herkes fikir belirtirse, belki çok verimli bir yapı ortaya çıkabilir...

Soruma geçmeden önce hemen kod ile cevabını vermek istiyorum:
class WordTypes (T)
{
  struct Dal (T)
  {
    T[] datas;
  }
 
  Dal[T] categories;
  string[] names;
 
  this(string[] isimler; Dal[T] dallar)
  {
    this.names = isimler;
    this.categories = dallar;
  }
}
Bir CSV verisi düşünün; bu aslında basit bir (satır x 3 sütunluk) veritabanı çizelgesi. Bir kaç sene evvel MySQL'in sitesinde (emin değilim, Oracle veya Sun'nın sitesinde olabilir) menüler/variantlar için sonsuz derinlikte genişleyebilen bu yapıyı okumuştum. Makaleyi bulamadığım için aklıma kalanlar ile aşağıdaki örnek verileri, yukarıdaki gibi hafızaya almayı düşünüyorum:

parrent/name/id
0;root;0
0;About;1
0;Products;2
2;semifinished;4
2;manufactured;5
0;Downloads;3
3;documents;6
3;pictures;7
3;files;8


Normalde File ile dosyayı açıp split() ile noktalıvirgüllere(separator) bölmemiz gerekir. Onları geçip şu şekilde kurulduğunu farz edelim...
void main() {
  alias WordTypes.Dal D;
  auto Dallar = new WordTypes!ubyte(
    [ "root", "About", "Products", "semifinished", "manufactured", "Downloads", "documents", "pictures", "files" ],
    [ 0 : D([ 1, 2, 3 ]), 2 : D([ 4, 5 ]), 3 : D([ 6, 7, 8 ]) ]
  );
}

Çok mu saçma oldu...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Sonuçta amaç bir klasör ağacı mı oluşturmak? Dosya sırayla taranabilir ve ağaç öylece büyütülebilir:


/
  About
  Products
    semifinished
    manufactured
  Downloads
    documents
    pictures
    files


Son gösterdiğin koddaki gibi kurulsa bazı bilgiler kapalı olarak geçmiş oluyorlar: Örneğin, "About" 1 numaralı indekste olduğu için onun numarasının 1 olduğunu bilebiliyoruz. Böyle kapalılıklar sorun çıkartabilir. Birisi tam anlamadan araya başka bir isim sıkıştırsa herşey kayabilir. (Örneğin, 'dallar' parametresinde "About"un karşılığının da boş olarak bulunması gerekiyor.)

Ali
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1913 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam kusura bakma çok ayrıntıya giremedim; verdiğin ağaç doğrudur ama benim nakletmem gerekirdi. Zaten kodları kafamdan yazmıştım ve bir kaç hata varmış. Az önce denedim recursive kısmı hariç istediğim gibi çalışıyor...

Demek ki kurduğum yapı mantıklı, ne dersin? Çalışan kod ama çok çok amatör görünümlüsü şöyle:
class WordTypes (T) {
  struct Dal { T[] dallar; }
  Dal[T] datas;
  string[] names;
 
  this(string[] isimler, Dal[T] dallar) {
    this.names = isimler;
    this.datas = dallar;
  }
 
  string submenu(int index) const {
    string result;
    auto menus = this.datas.values[index - 1].dallar;
 
    foreach(menu; menus) {
      result ~= format("  *%s\n", this.names[menu]);
      if(menu in this.datas) {
        //result ~= submenu(menu);
      }
    }
    return result;
  }
 
  override
  string toString() const {
    auto result = "________________\n";
    auto root = this.datas.values[0].dallar;
    
    foreach(menu; root) {
      result ~= format("%s\n", this.names[menu]);
      if(menu in this.datas) {
        result ~= submenu(menu);
      }
    }
    return result;
  }
}
 
import std.stdio, std.string;
 
void main() {
  alias WordTypes!int.Dal Dal;
  auto Dallar = new WordTypes!int([ "root",
    "About", "Products", "Downloads",
    "semifinished", "manufactured",
    "documents", "pictures", "files",
    "submenu1", "submenu2" ],
    [ 0 : Dal([ 1, 2, 3 ]), 2 : Dal([ 4, 5 ]), 3 : Dal([ 6, 7, 8 ]), 8 : Dal([9, 10]) ]
  );
  Dallar.writeln;
}/* Çıktısı:
________________
About
Products
  *semifinished
  *manufactured
Downloads
  *documents
  *pictures
  *files
*/
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
İşe yarıyorsa iyidir ama ben de fazla kibar söylemişim galibi. Şöyle daha dürüst olur: Kurucu parametreleri çok kullanışsız ve hataya açık olmuş. :) "About" ile "Products"ın arasına başka bir isim eklediğini düşün. Herşey kaymaz mı? Şimdi gidip ikinci kurucu parametresindeki bütün 0, 2, vs. numaraları bir arttırman gerekir.

"bazı bilgiler kapalı olarak geçmiş oluyorlar" derken buna değinmek istemiştim. "About"un numarasının 1 olduğu üstü kapalı olarak ve onun bulunduğu konum nedeniyle biliniyor. Öyle olmamalı. Onun 1 numaraya sahip olduğu açıkça bildirilmeli. (Yoksa üstteki paragraftaki gibi hatalar oluşur.)

Ek olarak, İngilizce veya Türkçe'de karar vermen gerek. Karışık olmuş. :) Bir de "data" zaten çoğuldur "datas" olmaz.

Ali
Avatar
Salih Dinçer #5
Üye Ock 2012 tarihinden beri · 1913 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Haklısın hocam çok "graphite" benzeri bir yapı oldu. Ekleme olduğunda dediğin gibi indeksler ötelenecek. Bu öngördüğüm bir şey ve MySQL gibi bir veritabanı kullanmadığım için dosya mecburen yeniden "generate" olacak. O yüzden büyük bir sorun değil...

Şu sıralar çok tembelim biraz daha sağlam kodlar yazmalıyım...:)

Bu arada tembel demişken İngilizce lazy'nin çoğulu ne hocam? Pek kullanılmadığından mı, yoksa zaten çoğul görünümlü bir şey olduğundan mı bulamıyorum. Bulabildiklerim:
  • a lazy (singular)
  • lazier (comparative)
  • laziest (superlative)
  • laziness (noun)
  • lazyish (adjective)
  • to laze (verb)
  • lysu (old english)
  • laysy (modern english)

Bu arada sözlükte her sözcük için tek kayıtlık (satırlık) veritabanı mı uygun olur, yoksa sözcüklerin diğer halleri de aynı statüde, farklı bir sözcük gibi mi dursun? Şu ana kadar 2000 sözcüğün veritabanını meydana getirdim. Bunların 500'ü aşkını "statü" gibi Türkçeye geçmiş...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
lazy'nin çoğulu ne

İngilizce'de yalnızca sıfat oluyor. Onun için çoğulu yok.

Bu arada sözlükte her sözcük için tek kayıtlık (satırlık) veritabanı mı uygun olur

Benim fikrim yok. Bence en mantıklı geleni seç. Kullanım sorunu olursa diğerini denersin.

Ali
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1913 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #4
acehreli:
... "bazı bilgiler kapalı olarak geçmiş oluyorlar" derken buna değinmek istemiştim. "About"un numarasının 1 olduğu üstü kapalı olarak ve onun bulunduğu konum nedeniyle biliniyor. Öyle olmamalı. Onun 1 numaraya sahip olduğu açıkça bildirilmeli. (Yoksa üstteki paragraftaki gibi hatalar oluşur.)

Ek olarak, İngilizce veya Türkçe'de karar vermen gerek. Karışık olmuş. :) Bir de "data" zaten çoğuldur "datas" olmaz.
Doğru anlaşabilmek çok önemliymiş...

Bu olgu hem aramızda, hem yazılım ile beynimizde gerçekleşiyor. Konumuz yazılım olunca da farkında olmadan her şey karışabiliyor. Ali hocam index değerlerine işaret etmişti ve "bazı bilgiler kapalı olarak geçmiş oluyorlar" demişti. Tam olarak aynı sorunumu tespit ettik bilmiyorum ama sanırım asıl karışıklığı giderdim:

auto root = this.datas.values[0].dallar;
// !!! -------------------^ 

Çünkü çağrşımsal dizi kullanıyordum ve ben neden "index'i yeniden sıralanmış" bir dizi döndürmesini istedim! Cevabını biliyorum ve altDallar'a ulaşamadığım için bunu yapmıştım ama nedense daha önce çalışmayan şimdi çalışıyor. Herhalde beyin ve yazılım arasındaki bir karışıklık...:)

Son kod aşağıda ve index değerleri değişmeden sınırsız altDal eklenebiliyor...
import std.stdio, std.array;
 
class WordTypes (T) {
  struct Dal { T[] altDallar; }
  Dal[T] dallar;
  string[] isimler;
 
  this(string[] isimler, Dal[T] altDallar) {
    this.isimler = isimler;
    this.dallar = altDallar;
  }
 
  string altMenü(int index = 0, int space = 0) const {
    string result;
     space += 2; // sağa doğru uzasın...
    foreach(dal; this.dallar[index].altDallar) {
      result ~= replicate(" ", space) ~ this.isimler[dal] ~ "\n";
      if(dal == index) {
         break; // kendisi içinde kendisi olmasın!
      } else if(dal in this.dallar) {
        result ~= altMenü(dal, space)// dönsün dursun...:)
      }
    }
    return result;
  }
}
 
void main() {
  string[] İsimler = [ "root", /* Görünmez kök */
                       "About", "Products", "Downloads", 
                       "semifinished", "manufactured",
                       "documents", "pictures", "files",
                       "New Menu", "submenu1", "submenu2" ];
 
  alias WordTypes!int.Dal Dal;
  Dal[int] altDallar = [ 0 : Dal( [ 1, 9, 2, 3 ] ),
                         2 : Dal( [ 4, 5 ]       ),
                         3 : Dal( [ 6, 7, 8 ]    ),
                         9 : Dal( [10, 11]       )
                       ];
  auto MENÜ = new WordTypes!int( İsimler, altDallar );
       MENÜ.altMenü.writeln;
  
  İsimler.length.writeln(" adet başlık kayıtlı...");
} /* Çıktısı:
  About
  New Menu
    submenu1
    submenu2
  Products
    semifinished
    manufactured
  Downloads
    documents
    pictures
    files
 
12 adet başlık kayıtlı...
*/
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4538 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Anlatmaya çalıştığım kırılganlık hâlâ var. Dikkatsiz (veya unutkan) bir programcı olduğum için kurala uymadım ve yeni klasörü sona değil, araya sıkıştırdım:
                       "About", "Products", "Downloads",
                       "Çamaşırlar",    // <-- araya sıkıştırdım
                       "semifinished", "manufactured",
Çıktısı karman çorman oldu:

  About
  files
    New Menu
    submenu1
  Products
    Çamaşırlar
    semifinished
  Downloads
    manufactured
    documents
    pictures

Ne yazık ki buradaki hata unutkan programcıda değil, programcıların unutkan olabileceklerini gözden kaçırmış olan asıl tasarımcıda.

Kırılganlık şurada: Örneğin "New Menu"nün 9 numaralı olduğu gibi bir varsayım var ama bu varsayım kodda hiçbir yerde görünmüyor. "New Menu" dizgisi ile 9 : Dal( [10, 11]       ) çağrışımsal dizi elemanı arasında hiçbir bağlantı yok.

Ali
Avatar
Salih Dinçer #9
Üye Ock 2012 tarihinden beri · 1913 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Veri kaynağı kod üzerinde olsa haklısın hocam...

Ancak veriler, otomatik olarak üretilen (menülerin yerleri bile değiştirilen) CSV dosyasından gelecek:

string data =`0;root;0
0;About;1
0;Products;2
0;Downloads;3
2;semifinished;4
2;manufactured;5
3;documents;6
3;pictures;7
3;files;8
0;New Menu;9
9;submenu1,10
9;submenu1,11`;

O yüzden böyle bir sorun olmayacak. Çünkü biri çağrışımsal olan her iki dizi aynı anda genişletilecek. Tabi yukarıdaki kaynaktan veri alındığında 9 numaralı kimliğe sahip dal en altta olur. Eğer 1 ile 2 arasında almak istersek bunun için sadece üst dalı yukarıya taşımamız yeterli.

Alt dallar, grup halinde rasgele karıştırılsa da parentId ile ilişkilendirilenlerin yanına gelmek zorundalar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Projeler Genel RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-12-16, 10:51:10 (UTC -08:00)