Aynı soru geçen gün D.learn haber grubunda soruldu:
http://forum.dlang.org/thread/mvztrmbrlyjlfjhypitz@forum.dlang.org
Tam bu işi yapan işlev yok ama orada üç yöntem gösterdim:
import std.stdio;
void removeAt(T : U[], U)(ref T dilim, size_t indeks) in {
assert(indeks <= dilim.length);
} body {
dilim = dilim[0..indeks] ~ dilim[indeks + 1 .. $];
}
void main()
{
string[] dizim=["1","2","3"];
dizim.removeAt(1);
assert(dizim == ["1", "3"]);
}
Yukarıdakinin bir sorunu var: dizim'in türü string olduğunda böyle bir işlem ancak ASCII metinlerle kullanılabilir. (string, UTF-8 kod birimlerinden oluştuğu için.) Bir de sakıncası var: removeAt hevesli bir işlev olduğu için dizi uzun olduğunda yavaş kalacaktır.
İkinci yöntem Unicode dizgileriyle de çalışır ama heveslilik [sakıncası onda da var. İşin güzeli, bu her türlü RandomAccessRange aralığıyla çalışır:
import std.stdio;
import std.range;
R removeAt(R)(R aralık, size_t indeks)
{
auto gerisi = aralık.save;
gerisi.popFrontN(indeks + 1);
return aralık[0 .. indeks] ~ gerisi;
}
void main()
{
string[] dizim=["1","2","3"];
dizim = dizim.removeAt(1);
assert(dizim == ["1", "3"]);
}
Üçüncü yöntem ise tembel olarak işliyor ve sonucu yine bir aralık olarak döndürüyor. Böylece sonuç tekrardan belki de çok uzun bir dizi olarak döndürülmemiş oluyor:
import std.stdio;
import std.range;
import std.algorithm;
auto removeAt(R)(R aralık, size_t indeks)
{
auto gerisi = aralık.save;
gerisi.popFrontN(indeks + 1);
return [aralık[0 .. indeks], gerisi].chain.joiner;
}
void main()
{
string[] dizim=["1","2","3"];
auto sonuç = dizim.removeAt(1);
assert(sonuç.array == ["1", "3"]);
}
'sonuç' tembel bir aralık olduğundan o aralıktan bir dizi oluşturmak gerektiğinde .array çağrılır. (Ama çoğu durumda gerekmez; yukarıda assert içinde kullanabilmek için çağırdım.)
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]