lua的table庫

 

函數列表:
table.insert(table,[ pos,] value)
table.remove(table[, pos])
table.concat(table[, sep[, i[, j]]])
table.sort(table[, comp])
數組



1. insert 和 remove 只能用於數組元素的插入和移出, 進行插入和移出時,會將後面的元素對齊起來。
    因此在 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 分隔。
    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,一次性把字符串拼接出來,只產生了一個字符串拷貝
       
lua



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);
        }
    看以上代碼,若是 a==b 時返回 true 且邊界上的幾個值是相等的話, sort_comp 就沒法阻止 i 繼續增加,直到超出邊界引起異常 attempt to compare number with nil;即便咱們對 a 和 b 進行非空判斷,也會由於 i 超過邊界而引起異常 invalid order function for sorting
    快速排序是什麼,lua 如何實現快速排序,能夠參考 lua 源碼中的描述,這裏很少介紹;
   
spa

相關文章
相關標籤/搜索