原帖鏈接:http://www.jb51.net/article/64711.htm#comments
有增注標識的地方為額外注釋,非原帖內容。
函數列表:(增注:只能用於數組!)
table.insert(table,[ pos,] value)
table.remove(table[, pos])
table.concat(table[, sep[, i[, j]]])
table.sort(table[, comp])
1. insert 和 remove 只能用於數組元素的插入和移出, 進行插入和移出時,會將后面的元素對齊起來。
(增注:和C++里對std::vector等容器使用iterator迭代器進行刪除類似)
所以在 for 循環中進行 insert 和 remove 的時候要注意插入和移除時是否漏掉了某些項:
local t = {1,2,3,3,5,3,6} for i,v in ipairs(t) do if v == 3 then table.remove(t,i) end end -- 錯誤,第四個 3 沒有被移除,ipairs 內部會維護一個變量記錄遍歷的位置,remove 掉第三個數字 3 之后,ipairs 下一個返回的值是 5 而不是 3
local t = {1,2,3,3,5,3,6} for i=1, #t do if t[i] == 3 then table.remove(t,i) i = i-1 end end -- 錯誤,i=i-1 這段代碼沒有用,i 的值始終是從 1 到 #t,for 循環里修改 i 的值不起作用
local t = {1,2,3,3,5,3,6} for i=#t, 1, -1 do if t[i] == 3 then table.remove(t,i) end end -- 正確,從后往前遍歷
local t = {1,2,3,3,5,3,6} local i = 1 while t[i] do if t[i] == 3 then table.remove(t,i) else i = i+1 end end -- 正確,自己控制 i 的值是否增加
2. concat 可以將 table 的數組部分拼接成一個字符串,中間用 seq 分隔。
(增注:對字符串的操作,一定要避免使用..符號!可以使用string.format進行操作,性能上比..要高得多)
lua 中字符串的存儲方式與 C 不一樣,lua 中的每個字符串都是單獨的一個拷貝,拼接兩個字符串會產生一個新的拷貝,如果拼接操作特別多,就會影響性能
local beginTime = os.clock() local str = "" for i=1, 30000 do str = str .. i end local endTime = os.clock() print(endTime - beginTime) -- 消耗 0.613 秒,產生了 30000 個字符串拷貝,但只有最后一個是有用的
local beginTime = os.clock() local t = {} for i=1, 30000 do t[i] = i end local str = table.concat(t, "") local endTime = os.clock() print(endTime - beginTime) -- 消耗 0.024 秒,利用 concat,一次性把字符串拼接出來,只產生了一個字符串拷貝
3. sort 可以將 table 數組部分的元素進行排序,需要提供 comp 函數,comp(a, b) 如果 a 應該排到 b 前面,則 comp 要返回 true 。
注意,對於 a==b 的情況,一定要返回 false :
local function comp(a,b) return a <= b end table.sort(t,comp) -- 錯誤,可能出現異常:attempt to compare number with nil
local function comp(a,b) if a == nil or b == nil then return false end return a <= b end table.sort(t,comp) -- 錯誤,可能出現異常:invalid order function for sorting
-- 也可能不報這個異常,但結果是錯誤的;
之所以 a==b 返回true 會引發這些問題,是因為 table.sort 在實現快速排序時沒有做邊界檢測: for (;;) { while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { // 未檢測邊界, i 會一直增加 if (i>=u) luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); } while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { // 未檢測邊界, j 會一直減少
if (j<=l) luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); } if (j<i) { lua_pop(L, 3); break; } set2(L, i, j); }
增注:下面為正確的寫法(這里省略了b == nil)
local function comp(a,b) if a == nil or a == b then
return false
end
return a < b end
table.sort(t,comp)