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