Alıntı (cos00kun):
> .byCodePoint
D'de char türü "karakter" kavramı değildir, UTF-8 kod birimidir. 'a' tek kod biriminden oluşur ve Unicode'un tasarımı gereği ASCII 'a' ile aynı kodlamaya sahiptir. O yüzden char'ı sanki "karakter"miş gibi kullanıyor ve bu ayrımın farkına bile varmıyoruz.
Oysa örneğin 'ç' iki char'dan '♠' üç char'dan oluşur.
byCodePoint, bu char'ları çözümser ve elemanları bize UTF-32 değerinde dchar'lar olarak sunar. (Bu otomatik çözümsemeyi çoğu Phobos aralık algoritması da yapar ama foreach yapmaz.)
Alıntı:
> dstringler
string nasıl char dizisi ise (yani, UTF-8 dizisi), dstring de dchar dizisidir (yani, UTF-32 dizisi).
Alıntı:
> Bu kağıtları diziye kopyalayıp ordan seçtikçe diziden remove etmek gibi bir yöntem mi daha idealdir?
D'nin aralık kavramı bu işe çok uygun: Tek dizi oluşturulabilir ve sonra elemanları baş taraftan birer birer veya örneğin dörder dörder ziyaret edilebilir. Bu işlem sırasında ana aralık (yani, deste) baş tarafından kısaltılır ve hic kopyalamadan bütün elemanlar masrafsızca görülebilir.
Olabildiğince temel olanaklar kullanarak:
// Hangi işlevin hangi modülde olduğunu açıkça gösteriyorum:
import std.stdio : writeln;
import std.algorithm : map;
import std.format : format;
import std.range : chunks;
import std.random : randomShuffle;
import std.uni : byCodePoint;
// Bunlar char dizileridir
enum renkler = "♠♡♢♣";
enum sayılar = "23456789JQKA";
struct Kağıt {
dchar renk; // Her Unicode karakterini barındırabilen tür
dchar sayı; // Bu char olabilirdi ama bunu da dchar yaptım
string toString() {
return format!"%s%s"(renk, sayı);
}
}
auto yeniElliİki() {
Kağıt[] deste;
foreach (renk; renkler.byCodePoint) {
foreach (sayı; sayılar.byCodePoint) {
deste ~= Kağıt(renk, sayı);
}
}
return deste;
// Yukarıdakinin yerine şu da olabilirdi:
/*
return
renkler
.map!(renk => sayılar.map!(sayı => Kağıt(renk, sayı)))
.joiner
.array;
*/
}
void main() {
// Sıralı bir deste
auto deste = yeniElliİki();
// Karıştırılıyor
randomShuffle(deste);
// Bundan sonra desteyi "aralık" olarak kullanabiliriz
writeln("Teker teker:");
foreach (kağıt; deste) {
writeln(kağıt);
}
// chunks(N), bir aralığın elemanlarını N'er N'er ziyater eder
writeln("Dörder dörder:");
foreach (el; deste.chunks(4)) {
writeln(el);
}
// Yukarıdaki iki döngü de aynı desteyi kullanır. Birinci deste
// yalnızca kendi aralığını tüketir. Zaten o yüzden aynı desteyi
// ikinci kere ziyaret edebildik. Gerektiğinde bir diziyi sıfırlamak için null atayabiliriz:
deste = null;
writeln("Deste şimdi boş: ", deste);
}
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]