openresty开发系列19--lua的table操作
openresty開發(fā)系列19--lua的table操作
Lua中table內(nèi)部實際采用哈希表和數(shù)組分別保存鍵值對、普通值;下標從1開始
不推薦混合使用這兩種賦值方式。
local color={first="red", "blue", third="green", "yellow"}
print(color["first"])???????????????? --> output: red
print(color[1])?????????????????????? --> output: blue
print(color["third"])???????????????? --> output: green
print(color[2])?????????????????????? --> output: yellow
print(color[3])?????????????????????? --> output: nil
一)table.getn 獲取長度
相關(guān)于取長度操作符寫作一元操作 #。
字符串的長度是它的字節(jié)數(shù)(就是以一個字符一個字節(jié)計算的字符串長度)。
對于常規(guī)的數(shù)組,里面從 1 到 n 放著一些非空的值的時候,它的長度就精確的為 n,即最后一個值的下標。
local tblTest1 = { 1, a = 2, 3 }
print("Test1 " .. table.getn(tblTest1))
此table的長度為2,可是明明是三個數(shù)值啊,這里要說明一下,getn 只能執(zhí)行數(shù)值型的table,即數(shù)值索引的值.
忽略哈希值類型的鍵值對map,即不包含字符索引值
local tblTest1 = { b=1, a = 2, 3 }
print("Test1 " .. table.getn(tblTest1))??? #輸出長度為1
local tblTest1 = { b=1, a = 2, c=3 }
print("Test1 " .. table.getn(tblTest1))??? #輸出長度為0
local tblTest1 = { 1, 2, 3 }
print("Test1 " .. table.getn(tblTest1))??? #輸出長度為3
在有個地方說明一下
--此table 雖然有[3]=6,也是數(shù)組型,但是不連續(xù)的,缺少了2的索引,所以輸出長度為1
local tblTest1 = { [3] = 6,c = 1, a = 2, [1]=3 }
print("Test1 " .. table.getn(tblTest1))? ?
--此table 數(shù)值索引是連續(xù) 到2,所以輸出長度為2
local tblTest1 = { [2] = 6,c = 1, a = 2, 3 }
print("Test1 " .. table.getn(tblTest1))? ?
=============================
獲取table長度,不區(qū)分數(shù)組和鍵值對
function table_length(t)
? local leng=0
? for k, v in pairs(t) do
??? leng=leng+1
? end
? return leng;
end
=================
特殊說明:
如果數(shù)組有一個"空洞"(就是說,nil 值被夾在非空值之間),那么 #t 可能是指向任何一個是 nil 值的前一個位置的下標(就是說,任何一個 nil 值都有可能被當成數(shù)組的結(jié)束)。
這也就說明對于有"空洞"的情況,table 的長度存在一定的 不可確定性。
關(guān)于nil的特別說明
local tblTest2 = { 1,nil,2}
對一個table中有nil值 取長度,會有很多不確定性,不同的luajit版本輸出的結(jié)果也不一樣
不要在 Lua 的 table 中使用 nil 值,如果一個元素要刪除,直接 remove,不要用 nil 去代替。
二)table.concat (table [, sep [, i [, j ] ] ])
對于元素是 string 或者 number 類型的表 table,
返回 table[i]..sep..table[i+1] ··· sep..table[j] 連接成的字符串。填充字符串 sep 默認為空白字符串。
起始索引位置 i 默認為 1,結(jié)束索引位置 j 默認是 table 的長度。如果 i 大于 j,返回一個空字符串。
local a = {1, 3, 5, "hello" }
print(table.concat(a))????????????? -- output: 135hello
print(table.concat(a, "|"))???????? -- output: 1|3|5|hello
print(table.concat(a, " ", 2, 4))?? -- output: 3 5 hello
print(table.concat(a, " ", 4, 2))?? -- output:
在介紹string字符串那邊有個字符串拼接,是用.. 這個符號進行的
local str = "a" .. "b" .. "c"..........................? 推薦用concat
三)table.insert (table, [pos ,] value)
在(數(shù)組型)表 table 的 pos 索引位置插入 value,其它元素向后移動到空的地方。
pos 的默認值是表的長度加一,即默認是插在表的最后。
local a = {1, 8}???????????? --a[1] = 1,a[2] = 8
table.insert(a, 1, 3)?? --在表索引為1處插入3
print(a[1], a[2], a[3])
table.insert(a, 10)??? --在表的最后插入10
print(a[1], a[2], a[3], a[4])
-->output
3?? 1?? 8
3?? 1?? 8?? 10
四)table.remove (table [, pos])
在表 table 中刪除索引為 pos(pos 只能是 number型)的元素,并返回這個被刪除的元素,
它后面所有元素的索引值都會減一。pos 的默認值是表的長度,即默認是刪除表的最后一個元素。
local a = { 1, 2, 3, 4}
print(table.remove(a, 1)) --刪除速索引為1的元素
print(a[1], a[2], a[3], a[4])
print(table.remove(a))?? --刪除最后一個元素
print(a[1], a[2], a[3], a[4])
-->output
1
2?? 3?? 4?? nil
4
2?? 3?? nil nil
五)table.sort (table [, comp])
local a = { 1, 7, 3, 4, 25}
table.sort(a)?????????? --默認從小到大排序
print(a[1], a[2], a[3], a[4], a[5])
-->output
1?? 3?? 4?? 7?? 25
按照給定的比較函數(shù) comp 給表 table 排序,也就是從 table[1] 到 table[n],這里 n 表示 table 的長度。
比較函數(shù)有兩個參數(shù),如果希望第一個參數(shù)排在第二個的前面,就應該返回 true,否則返回 false。
如果比較函數(shù) comp 沒有給出,默認從小到大排序。
local function compare(x, y) --從大到小排序
?? return x > y???????? --如果第一個參數(shù)大于第二個就返回true,否則返回false
end
table.sort(a, compare) --使用比較函數(shù)進行排序
print(a[1], a[2], a[3], a[4], a[5])
-->output
25? 7?? 4?? 3?? 1
六)table.maxn (table)
返回(數(shù)組型)表 table 的最大索引編號;如果此表沒有正的索引編號,返回 0。
local a = {}
a[-1] = 10
print(table.maxn(a))
a[5] = 10
print(table.maxn(a))
-->output
0
5
七)table 判斷是否為空
大家在使用 Lua 的時候,一定會遇到不少和 nil 有關(guān)的坑吧。
有時候不小心引用了一個沒有賦值的變量,這時它的值默認為 nil。如果對一個 nil 進行索引的話,會導致異常。
如下:
local person = {name = "Bob", sex = "M"}
-- do something
person = nil
-- do something
print(person.name)
報錯person為nil了
然而,在實際的工程代碼中,我們很難這么輕易地發(fā)現(xiàn)我們引用了 nil 變量。
因此,在很多情況下我們在訪問一些 table 型變量時,需要先判斷該變量是否為 nil,例如將上面的代碼改成:
local person = {name = "Bob", sex = "M"}
-- do something
person = nil
-- do something
if person ~= nil then
? print(person.name)
else
? print("person 為空")
end
對于簡單類型的變量,我們可以用 if (var == nil) then 這樣的簡單句子來判斷。
我們?nèi)绻袛鄑able類型的對象是否為空,那如何判斷呢?
我們思考一下,判斷table是否為空有兩種情況:
第一種table對象為nil;
第二種table對象為{},代表沒有鍵值對,但不為nil。
那么我們一般的判斷邏輯就應該是 table == nil? 或者 table的長度為0? 就表示為空
下面我們看看以下例子:
local a = {}
local b = {name = "Bob", sex = "Male"}
local c = {"Male", "Female"}
local d = nil
if a == nil then
??? print("a == nil")
end
if b == nil then
??? print("b == nil")
end
if c == nil then
??? print("c == nil")
end
if d== nil then
??? print("d == nil")
end
?
if next(a) == nil then
??? print("next(a) == nil")
end
if next(b) == nil then
??? print("next(b) == nil")
end
if next(c) == nil then
??? print("next(c) == nil")
end
以上有幾個注意點,涉及到table類型的長度
(#a)?? --"#"表示為獲取table類型的長度,類似table.getn()
因為a為{},所以長度為0.
我們再看(#b) ,依然輸出的是0,但b是有值的啊。
我們再看(#c),輸出的是2,這個是怎么回事。這里就是之前在table類型的課程中已經(jīng)介紹的獲取table的長度,
只是獲取的是 數(shù)組型的長度,不包含map型的。
我們再往下看 if a == nil then? 在判斷 a是否為nil,明顯a不為nil
if next(a) == nil then中的next是什么意思呢?
next (table [, index])
功能:允許程序遍歷表中的每一個字段,返回下一索引和該索引的值。
參數(shù):table:要遍歷的表
index:要返回的索引的前一索中的號,當index為nil[]時,將返回第一個索引的值,
????? 當索引號為最后一個索引或表為空時將返回nil
next(a) 就是返回第一個索引的值,a的第一個索引是沒有值的,那么next(a) 就為nil
所以next方法經(jīng)常用來判斷 table中是否有值。
下面的語句相信大家就能看懂了。
綜合以上代碼,我們判斷table是否為空,就不能簡單的判斷table長度是否為0,而是判斷索引值。
所以要判斷table是否為空應該按照以下進行判斷
function isTableEmpty(t)
??? return t == nil or next(t) == nil
end
八)ipairs和pairs的區(qū)別
為了看出兩者的區(qū)別,首先定義一個table:
a={"Hello","World";a=1,b=2,z=3,x=10,y=20;"Good","Bye"} ?
for i, v in ipairs(a) do
?? ?print(v)
end
輸出的結(jié)果是:
Hello
World
Good
Bye
可見ipairs并不會輸出table中存儲的鍵值對,會跳過鍵值對,然后按順序輸出table中的值。
再使用pairs對其進行遍歷:
for i, v in pairs(a) do
?? ?print(v)
end
輸出的結(jié)果是:
Hello
World
Good ?
Bye? ?
1??? ?
10?? ?
2??? ?
20?? ?
3??? ?
可見pairs會輸出table中的值和鍵值對,并且在輸出的過程中先按順序輸出值,再亂序輸出鍵值對。
這是因為table在存儲值的時候是按照順序的,但是在存儲鍵值對的時候是按照鍵的哈希值存儲的,
并不會按照鍵的字母順序或是數(shù)字順序存儲。
對于a來說,如果執(zhí)行print(a[3]),輸出的結(jié)果也會是Good。也就是說table并不會給鍵值對一個索引值。
也就是說ipairs只是按照索引值順序,打印出了table中有索引值的數(shù)據(jù),沒有索引值的不管。
而pairs是先按照數(shù)組索引值打印,打印完成后再按照哈希鍵值對的鍵的哈希值打印它的值。
LuaJIT 2.1? 新增加的 table.new 和 table.clear 函數(shù)是非常有用的。
前者主要用來預分配 Lua table 空間,后者主要用來高效的釋放 table 空間,并且它們都是可以被 JIT 編譯的。
轉(zhuǎn)載于:https://www.cnblogs.com/reblue520/p/11433496.html
總結(jié)
以上是生活随笔為你收集整理的openresty开发系列19--lua的table操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openresty开发系列18--lua
- 下一篇: 微信小程序实时将less编译为wxss