Lua極簡(jiǎn)入門(十一)——table類庫(kù)

table庫(kù)封裝了一些常用的方法,可以在日常的列表操作時(shí)提供便利,先看一下table中提供的一些方法。

方法 描述
table.concat(list, sep, i, j) 對(duì)數(shù)組進(jìn)行拼接,返回一個(gè)字符串
table.insert(list, pos, value) 將元素插入到指定的數(shù)組位置
table.move(a1, f, e, t, a2) 將a1數(shù)組從f位置開始到e位置結(jié)束的元素復(fù)制到a2,從a2的t位置開始
table.pack(...) 將參數(shù)封包為一個(gè)table,數(shù)組序列從1開始,同時(shí)返回一個(gè)n的key,描述參數(shù)的數(shù)量
table.remove(list, pos) 將指定位置的元素刪除
table.sort(list, comp) 對(duì)數(shù)組進(jìn)行排序
table.unpack(list, i, j) 將數(shù)組的位置i開始到j(luò)位置結(jié)束,返回?cái)?shù)組中的元素

添加與刪除

table.insert(t, pos, value)可以將value插入到指定的pos位置,如果pos不是最后位置,需要移動(dòng)pos以及后續(xù)的所有元素,并將value插入到空出的pos位置。如果直接調(diào)用table.insert(t, value),則直接將元素value添加到數(shù)組的末尾。

local t = {}
table.insert(t, "a")    -- t為空,則a為第一個(gè)位置
print(t[1])
-->> a
table.insert(t, 1, "b") -- 將位置1插入元素b,原來的a元素后移指2位置

for i, v in pairs(t) do
    print(i, v)
end
-->> 1  b
-->> 2  a

local a = { "a", "b", "c" }
table.insert(a, 2, "ray")   -- 2位置插入ray,原來的b、c移動(dòng)到位置3、4
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  a
-->> 2  ray
-->> 3  b
-->> 4  c

刪除方法與插入方法類似,table.remove(list, pos),將從pos位置刪除元素,并返回該位置的元素,后續(xù)的元素會(huì)前移;如果不指定pos參數(shù),table.remove(list)將刪除最后一個(gè)元素。

local t = { "a", "b", "c", "d" }
local d = table.remove(t, 2)
print(d)
-->> b
local d2 = table.remove(t)
print(d2)
--> d

排序

對(duì)于數(shù)組排序功能較為常見,一般情況如果使用簡(jiǎn)單數(shù)組,可以直接使用table.sort(t),即可實(shí)現(xiàn)升序排序(默認(rèn)為小于操作,即比較函數(shù)中第一個(gè)元素小于第二個(gè)元素);如果復(fù)雜table或者要按降序等排序,需要傳遞第二個(gè)參數(shù)(排序函數(shù)),降序?yàn)楸容^函數(shù)中第一個(gè)元素大于第二個(gè)元素。

local t = { 8, 5, 9, 3, 5, 4, 1 }
table.sort(t)
for i, v in pairs(t) do
    print(i, v)
end
-->> 1  1
-->> 2  3
-->> 3  4
-->> 4  5
-->> 5  5
-->> 6  8
-->> 7  9
local a = { "g", "a", "b", "e", "z", "y" }
table.sort(a)
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  a
-->> 2  b
-->> 3  e
-->> 4  g
-->> 5  y
-->> 6  z

實(shí)現(xiàn)降序時(shí),提供一個(gè)比較函數(shù),function(a,b),其中a、b分別為數(shù)組的兩個(gè)比較元素。

local a = { "g", "a", "b", "e", "z", "y" }
table.sort(a, function(i, j)    -- 比較函數(shù),降序?yàn)榈谝粋€(gè)元素參數(shù)大于第二個(gè)元素參數(shù),升序?yàn)樾∮?    return i > j
end)
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  z
-->> 2  y
-->> 3  g
-->> 4  e
-->> 5  b
-->> 6  a

排序還可以對(duì)一些復(fù)雜的table進(jìn)行操作,比如有一個(gè)對(duì)象存儲(chǔ)的為學(xué)生姓名及分?jǐn)?shù),按分?jǐn)?shù)從高到低進(jìn)行排序。

local students = {
    { name = "ray", score = 99 },
    { name = "hh", score = 77 },
    { name = "xx", score = 89 },
    { name = "xy", score = 90 },
    { name = "zs", score = 60 },
    { name = "ls", score = 100 },
}

table.sort(students, function(s1, s2)
    return s1.score > s2.score
end)

for _, v in pairs(students) do
    print(v.name, v.score)
end
-->> ls 100
-->> ray    99
-->> xy 90
-->> xx 89
-->> hh 77
-->> zs 60

移動(dòng)及封包

table.move(a1, f, e, t, a2),可以按參數(shù)指定位置的元素復(fù)制到指定起始位置的另外一個(gè)table中,類似于數(shù)組復(fù)制。

這里,我們創(chuàng)建一個(gè)數(shù)組,長(zhǎng)度為4,將從該數(shù)組的1位置到3位置共三個(gè)元素復(fù)制到b數(shù)組,b數(shù)組從2位置開始接收數(shù)據(jù)。

local a = { 4, 5, 6, 7 }
local b = {}
table.move(a, 1, 3, 2, b)   -- 這里的位置參數(shù)均不能缺省
for i, v in pairs(b) do
    print(i, v)
end
-->> 2  4
-->> 3  5
-->> 4  6

table.pack(...)函數(shù)可以將一些散列的參數(shù),封裝到一個(gè)table中,并將接收的參數(shù)個(gè)數(shù),以key=n作為最后一個(gè)元素插入到table中,之后將該table返回給調(diào)用者。

local a = table.pack("ray", { 1, 2, 3 }, "hh", { name = "hh" })
print(a.n)

for i, v in pairs(a) do
    if type(v) ~= "table" then
        print(i, v)
    else
        for j, val in pairs(v) do   -- 這里只是演示,不考慮更多層數(shù)組嵌套
            print(i, j, val)
        end
    end
end
-->> 4  --參數(shù)長(zhǎng)度為4
-->> 1  ray     -- 第一個(gè)位置元素
-->> 2  1   1   -- 第二個(gè)位置為數(shù)組,循環(huán)數(shù)組,第二個(gè)位置為嵌套數(shù)組位置
-->> 2  2   2
-->> 2  3   3
-->> 3  hh
-->> 4  name    hh  -- 第四個(gè)位置為table,第二個(gè)位置為table的key
-->> n  4   -- 參數(shù)長(zhǎng)度

table.unpack(list, i, j)table.pack(...)功能相反,將一個(gè)數(shù)組拆解,并返回指定位置的元素。

local a = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }
local z, x, c, v = table.unpack(a)  -- 返回全部元素
print(z,x,c,v)
-->> ray    table: 0000000000199dc0 hh  table: 0000000000199cc0
local x, c = table.unpack(a, 2, 3)
for i, v in pairs(x) do -- 第二個(gè)位置為table
    print(i, v)
end
-->> 1  1
-->> 2  2
-->> 3  3
print(c)    -- 字符串hh
-->> hh

連接

table.concat(list, sep, i, j)函數(shù)可以將一個(gè)table指定為進(jìn)行拼接,按照指定的分割符分割,返回一個(gè)字符串。在之前的章節(jié)中曾經(jīng)用到過。其中分割符,位置均可省略,分割符省略時(shí),默認(rèn)為空,位置省略,則默認(rèn)全部拼接。

local t = { "hello", "lua", ",", "very", "good", "!" }
print(table.concat(t, " "))
-->> hello lua , very good !
print(table.concat(t, " ", 1, 2))   -- 從table的第一個(gè)位置開始,到第二個(gè)元素進(jìn)行拼接
-->> hello lua

如果數(shù)組中嵌套數(shù)組時(shí),直接使用拼接函數(shù)將會(huì)異常。如上一小節(jié)中的實(shí)例數(shù)組:

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }
print(table.concat(t, " "))
-->> invalid value (table) at index 2 in table for 'concat'

為了使連接函數(shù)更具備通用性,可以對(duì)concat進(jìn)行封裝,使用遞歸調(diào)用。(只能處理普通的數(shù)組嵌套)

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }

function concat2(t)
    if type(t) ~= "table" then
        return t
    end
    -- 是數(shù)組進(jìn)行數(shù)組拼接,為了無限遞歸,可以再次循環(huán)
    local tmp = {}
    for i = 1, #t do
        tmp[i] = concat2(t[i])
    end
    -- 再次拼接,此時(shí)都是基礎(chǔ)數(shù)組
    return table.concat(tmp, " ")
end

print(concat2(t))
-->> ray 1 2 3 hh

在這個(gè)例子中,第四個(gè)元素為一個(gè)對(duì)象table,因此上述方放仍然無法拼接該table。添加對(duì)象table的支持拼接方法:

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }

function concat2(t)
    if type(t) ~= "table" then
        return t
    end
    -- 是數(shù)組進(jìn)行數(shù)組拼接,為了無限遞歸,可以再次循環(huán)
    local tmp = {}
    for i, v in pairs(t) do
        if type(i) ~= "number" then
            tmp[#tmp + 1] = i .. "=" .. concat2(v)
        else
            tmp[i] = concat2(v)
        end
    end
    -- 再次拼接,此時(shí)都是基礎(chǔ)數(shù)組
    return table.concat(tmp, " ")
end

print(concat2(t))
-->> ray 1 2 3 hh name=hh
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容