19 Tablo Kütüphanesi

19 Tablo Kütüphanesi

table kütüphanesi tabloları diziler gibi manipüle etmek için yardımcı fonksiyonlardan oluşur. Listelere öğe ekleme ve çıkarma, dizinin öğelerini sıralama ve dizideki tüm stringleri birleştirmek için fonksiyonlar sağlar.

19.1 Ekleme ve Çıkarma

table.insert fonksiyonu bir dizinin verilen bir konumuna öğe ekler, alan açmak için diğer öğeleri üste taşır. Örneğin t, {10,20,30} şeklinde bir dizi ise table.insert(t,1, 15) çağrısından sonra t, {15,10,20,30} şeklini alacak. Özel (ve sık) bir durum olarak, konum belirtmeden insert'i çağırırsak öğeyi dizinin sonuna ekler (ve bu nedenle hiçbir öğe taşınmaz). Örnek olarak devamdaki kod, satır satır program girdisini okur ve tüm bu satırları bir dizide depolar:

t = {}
for satir in io.lines() do
    table.insert(t, satir)
end
print(#t) --> (okunan satır sayısı)

(Lua 5.0'da bir listeye öğe eklemede bu kullanım yaygın olsa da 5.1'de t[#t+1]=satir kullanımı tercih edilmeli.)

table.remove fonksiyonu  bir dizinin verilen bir konumundan öğe çıkartır(ve döndürür), alanı kapatmak için diğer öğeleri alta taşır. Bir konum belirtilmeden çağrıldığında dizinin son öğesini çıkarır.

Bu iki fonksiyonla yığınları(stack), kuyrukları(queue) ve çift uçlu kuyrukları(deque) uygulamak basittir. t = {} şeklinde yapıları ilkleyebiliriz. push işlemi table.insert(t, x) ile eşdeğerdir; pop işlemi table.remove(t) ile eşdeğerdir. table.insert(t,1,x) çağrısı yapının diğer ucuna ekleme yapar(gerçekte başına) ve table.remove(t,1) bu uçtan kaldırır. Son iki işlem öğeleri yukarı ve aşağı hareket ettirmesi gerektiği için özellikle verimli değildir. Bununla birlikte table kütüphanesi bu fonksiyonları C'de uyguladığından bu döngüler çok masraflı değildir velhasıl bu uygulama küçük diziler için yeterince iyidir (birkaç yüz öğeye kadar).

19.2 Sıralama


Daha önce gördüğümüz üzere diziler ile ilgili bir diğer yararlı fonksiyon table.sort 'dur. sıralanacak dizi artı isteğe bağlı bir sıralama fonksiyonu alır. Bu sıralama fonksiyonu iki argüman alır ve ilk argüman seri dizide birinci geldiğinde true döndürmelidir. Bu fonksiyon sağlanmazsa sort varsayılan olarak 'den-küçük işlemini kullanır ('<' operatörüne karşılık gelir).

Yaygın bir hata, tablonun indekslerini sıralamaya çalışmaktır. Bir tabloda, indeksler bir küme formundadır ve herhangi bir sırası yoktur. Onları sıralamak istiyorsanız, onları bir diziye kopyalamanız ve ardından diziyi sıralamanız gerekir. Bir örnek görelim. Bir kaynak dosyasını okuduğunuzu ve her bir fonksiyon adı için bu fonksiyonun tanımlandığı satırın yerini veren bir tablo oluşturduğunuzu varsayalım; bunun gibi bir şey:

lines = {
    luaH_set = 10,
    luaH_get = 24,
    luaH_present = 48
}

Şimdi alfabetik sırayla bu fonksiyon adlarını yazdırmak istiyorsunuz. Bu tabloyu pairs ile dolaşırsanız isimler rasgele bir sırada görünür. Bunları direkt sıralayamazsınız çünkü bu isimler tablonun anahtarlarıdır. Ancak onları bir diziye koyduğunuzda onları sıralayabilirsiniz. İlkin bu adlarla bir dizi oluşturmanız ardından sıralamanız ve nihayetinde sonucu yazdırmanız gerekir:

a = {}
for n in pairs(lines) do a[#a + 1] = n end
table.sort(a)
for i, n in ipairs(a) do print(n) end

Dikkat, Lua için diziler de herhangi bir sıraya sahip değildir (sonuçta tablodurlar). Ancak nasıl sayılacağını biliyoruz bu şekilde sıralı indekslerle diziye eriştiğimiz sürece sıralı değerler elde ederiz. Bu nedenle pairs'den ziyade ipairs ile dizileri dolaşmalısınız. İlki, 1, 2, . . .  anahtar sırasını, ikincisi tablonun doğal keyfi sırasını yükler.

Daha gelişmiş bir çözüm olarak, anahtarlarının sırasını takip edildiği bir tabloyu dolaşan bir iteratör yazabiliriz. İsteğe bağlı f parametresi, alternatif bir sıralama belirtilmesine izin verir. ilkin dizide anahtarları sıralar ve ardından diziyi dolaşır. Her adımda, orijinal tablodan anahtar ve değer döndürür:

function pairsByKeys(t, f)
    local a = {}
    for n in pairs(t) do a[#a + 1] = n end
    table.sort(a, f)
    local i = 0 -- yineleme değişkeni
    return function()
        -- yineleme fonksiyonu
        i = i + 1
        return a[i], t[a[i]]
    end
end

Bu fonksiyonla,  fonksiyon adlarını alfabetik sıralı yazdırmak kolay:

for name, line in pairsByKeys(lines) do
    print(name, line)
end

19.3 Birleştirme


Hali hazırda bölüm 11.6'da table.concat 'ı gördük. stringler listesi alır ve tüm bu stringleri birleştirmenin sonucunu döndürür. İsteğe bağlı ikinci argüman, listenin stringleri arasına eklenecek bir string ayırıcı belirtir. fonksiyon aynı zamanda birleştirilecek ilk ve son string indekslerini belirten iki isteğe bağlı argüman daha kabul eder.

Bir sonraki fonksiyon table.concat'ın ilginç bir genişletilmişidir. iç içe stringlerin listelerini kabul eder:

function rconcat(l)
    if type(l) ~= "table" then return l end
    local res = {}
    for i = 1, #l do
        res[i] = rconcat(l[i])
    end
    return table.concat(res)
end

Herbir liste elemanı için, rconcat  olası iç içe listeyi birleştirmek için yinelemeli olarak kendini çağırır. Ardından tüm kısmi sonuçları birleştirmek için orijinal table.concat'i çağırır.

print(rconcat {{"ne", {" güzel"}}, " ve", {{" uzun"}, {" liste"}}})
--> ne güzel ve uzun liste

Hiç yorum yok:

Yorum Gönder