August 22

Merhaba,

Belki ismi EnumArray olmalıydı bilemiyorum! Az önce yazdığım kodu, eski bir arkadaşımın verdiği 4-5 satırlık ilham neticesinde paylaşmaya karar verdim. Çünkü bence çok mükemmel ve neredeyse en ufak bir hata yok? Belki %90 hatasızdır bilemiyorum çünkü unittest dışında çok test etmedim. Ama geliştirmeye açık olabilir.

Biz genelde enum'ları çok sık kullanırız ve dizi halinde pek az kullansak da hayatı kolaylaştıracak (özellikle indexOf ve başa ekleme özelliği kesinlikle başarılı. Çünkü veri dizge (string) olarak tutulmuyor ama isterseniz dizge veya sayı olarak da ekleyebilir ya da kişileştirmeye açık tür (E) ile de diziyi genişletebilirsiniz.

Bence kusursuz, sizce?

struct ConsArray(E)
{
  E[] list;
  size_t index;

  void insertFront(T)(T value, int line = __LINE__) {
    static if (is(T == string))
    {
      list = indexOf!E(value, line) ~ list;
    }
    else list = cast(E)value ~ list;
  }

  auto opIndex(size_t i) { return list[i]; }
  auto length() { return list.length; }

  bool empty() { return index == length; }
  auto front() { return list[index]; }
  void popFront() { ++index; }

  void removeFront() { list = list[1..$]; }
  void removeBack() { list = list[0..$ - 1]; }

  void opOpAssign(string op : "~", T)(T value) {
    this.list ~= cast(E)value;
  }

  auto indexOf(E)(string element, int line = __LINE__) {
    import std.conv : to;

    E count;
    bool error = true;

    while (count < count.max) {
      if (count.to!string == element) {
        error = false;
        break;
      }
      ++count;
    }

    if (error)
    {
      line.writefln!"Kod içinde (%s. satır) hata olabilir çünkü...";
      throw new Exception("Geçersiz değer, lütfen geçerli bir değer girin.");
    }
    return count;
  }
}

unittest
{
  enum isim { Ali, Cengiz, Kaan, Mahmut, Salih }
  ConsArray!isim isimler;

  isimler ~= 0;
  isimler ~= 1;

  isimler ~= isim.Ali;
  isimler ~= isimler[0];

  isimler ~= isim.Salih;
  isimler.removeFront();
  isimler.insertFront(4);

  isimler.insertFront("Kaan");
  isimler.writeln; /* Çıktısı:

  [Kaan, Salih, Cengiz, Ali, Ali, Salih]

  */
}

SDB@79

August 22

On Thursday, 22 August 2024 at 08:53:09 UTC, Salih Dincer wrote:

>

Merhaba,

Belki ismi EnumArray olmalıydı bilemiyorum!

Kabul o kadar mükemmel değil, öncelikle şunları güncelledim:

  enum isim { ALİ, Cengiz, Kaan, Mahmut, Salih }

  ref E opIndex(size_t i) { return list[i]; }

  void opOpAssign(string op : "~", T)(T value, int line = __LINE__) {
    static if (is(T == string))
    {
      list ~= indexOf!E(value, line);
    }
    else list ~= cast(E)value;
  }

Bunun dışında gelebilecek bir eleştiriye şimdiden yanıt verebilirim. Denilebilir ki "zaten bir string array yapabiliriz (örn. alias strings = immutable(char[])[]) öyleyse neden yeni bir tür tanımlayıp ekleyeceğimiz elemanları burada ekstradan tanımlayayım...

Evet, doğru? Aşağıdaki örneğin ilk satırını açtığınızda strings bir dizidir ve her elemanı string'dir ve immutable olduğu için const gibi davranacaktır ama tıpkı benim yapmaya çalıştığım gibi de listeye eleman eklenebilecektir. Özetle nasıl enum'ı değiştiremiyoruz, hacking yapmazsanız o listedeki elemanlar 1 kere eklenir ve içeriği değiştirilemez (ALİ'nin Ali yapılmaya çalışılması gibi) ve gördüğünüz gibi UTF desteği mükemmel:

  //alias strings = immutable(char[])[];/*
  alias strings = char[][];//*/
  strings str;
  foreach(s; [ "Kaan", "Salih","Cengiz",
               "Mahmut", "ALİ", "ALİ", "Salih"]) {
    str ~= s.dup;
  }
  str[4].writeln;
  isimler[4].writeln("\n");

  str[4] = "Ali".dup;
  isimler[4] = isim.Kaan;

  str[4].writeln;
  isimler[4].writeln("\n");
  isimler.writeln;
}
/* Sonraki Çıktı:

   ALİ
   ALİ

   Ali
   Kaan

*/

Olası diğer faydalarını vurgulamama gerek yok sanırım, gayet iyi...

SDB@79