-- lua扩展 -- table扩展 function table.indexof(array, value, begin) for i = begin or 1, #array do if array[i] == value then return i end end return false end -- 返回table大小 table.size = function(t) local count = 0 for _ in pairs(t) do count = count + 1 end return count end -- 判断table是否为空 table.empty = function(t) return not next(t) end -- 判断数值是否在范围内 table.between = function(t, v) return not t or (v >= t[1] and (t[2] == -1 or v <= t[2])) end -- 返回table索引列表 table.indices = function(t) local result = {} for k, v in pairs(t) do table.insert(result, k) end return result end -- 返回table值列表 table.values = function(t) local result = {} for k, v in pairs(t) do table.insert(result, v) end return result end -- 浅拷贝 table.clone = function(t, nometa) local result = {} if not nometa then setmetatable(result, getmetatable(t)) end for k, v in pairs(t) do result[k] = v end return result end --清空表 table.clear = function(array) if type(array) ~= "table" then return end for k, _ in pairs(array) do array[k] = nil end end -- 深拷贝 table.copy = function(t, nometa) local result = {} if not nometa then setmetatable(result, getmetatable(t)) end for k, v in pairs(t) do if type(v) == "table" then result[k] = table.copy(v) else result[k] = v end end return result end table.merge = function(dest, src) for k, v in pairs(src) do dest[k] = v end end -- 数组全等 table.congruent = function(arr1, arr2, sortFunc) if type(arr1) ~= "table" or type(arr2) ~= "table" then return false end if #arr1 ~= #arr2 then return false end arr1 = table.copy(arr1) arr2 = table.copy(arr2) local func = function(l, r) return l < r end func = sortFunc or func -- 排序来防止相同元素干扰 table.sort(arr1, func) table.sort(arr2, func) for k, v in pairs(arr1) do if v ~= arr2[k] then return false end end return true end table.array_merge = function(dest, src, unique) local insert = unique and table.unique_insert or table.insert for k, v in pairs(src) do insert(dest, v) end return dest end table.sum = function(tb, key) local sum = 0 for k, v in pairs(tb) do sum = sum + (key and v[key] or v) end return sum end table.unique_insert = function(t, val) for k, v in pairs(t) do if v == val then return end end table.insert(t, val) end table.delete = function(t, val) for k, v in pairs(t) do if v == val then table.remove(t, k) break end end end -- 按索引序列找到对应值 -- 如:参数为 tb,a,b,c 返回tb[a][b][c] table.get_value = function(t, ...) if not t then return end local path = {...} local res = t for k, v in ipairs(path) do if res[v] then res = res[v] else return end end return res end table.include = function(array, val) if array and val then for _, v in pairs(array) do if v == val then return true end end end return false end -- 查找表中元素对应key table.find = function(tbl, val) if tbl and val then for k, v in pairs(tbl) do if v == val then return k end end end end --根据table某个字段获取值,array所有值为table结构 table.key_find = function(array, key, val) for k, v in pairs(array) do if v[key] == val then return v, k end end return nil end -- 根据键找值最大的一个 table.find_max = function(array, key) local tmp for k, v in pairs(array) do if not tmp then tmp = v elseif key and tmp[key] < v[key] then tmp = v elseif not key and tmp < v then tmp = v end end return tmp end -- 根据键找值最小的一个 table.find_min = function(array, key) local tmp for k, v in pairs(array) do if not tmp then tmp = v elseif key and tmp[key] > v[key] then tmp = v elseif not key and tmp > v then tmp = v end end return tmp end table.key_delete = function(array, key, val) for k, v in ipairs(array) do if v[key] == val then table.remove(array, k) return v end end end --删除所有v[key] = val的值 table.key_delete_all = function(array, key, val) local i = 1 while i <= #array do if array[i][key] == val then table.remove(array, i) else i = i + 1 end end end --删除多个数据 table.array_delete = function(array, t_val) for k, v in pairs(t_val) do table.delete(array, v) end end --检测某个值是否在table里面 table.member = function(array, val) for k, v in ipairs(array) do if v == val then return true end end return false end --连接 table.link = function(dest, obj) for k, v in pairs(obj) do table.insert(dest, v) end end table.fori_each = function(t, f) for k, v in pairs(t) do if f(k, v) then return end end end table.to_key_value_array = function(source) local arr = {} for k, v in pairs(source) do table.insert(arr, tostring(k)) table.insert(arr, v) end return arr end -- 数组倒序 table.reverse = function(src) if not src or #src <= 1 then return src end local ret = {} for i = #src, 1, -1 do table.insert(ret, src[i]) end return ret end table.random_array = function(arr) local tmp, index for i = 1, #arr - 1 do index = math.random(i, #arr) if i ~= index then tmp = arr[index] arr[index] = arr[i] arr[i] = tmp end end end table.arry_merge = function(dest, src) for _, v in ipairs(src) do table.insert(dest, v) end end -- string扩展 -- 下标运算 -- do -- local mt = getmetatable("") -- local _index = mt.__index -- mt.__index = function(s, ...) -- local k = ... -- if "number" == type(k) then -- return _index.sub(s, k, k) -- else -- return _index[k] -- end -- end -- end -- 字符串长度计算(一个汉字长度为1) string.char_num = function(str) local lenInByte = #str local count = 0 local i = 1 while true do local curByte = string.byte(str, i) if i > lenInByte then break end local byteCount = 1 if curByte > 0 and curByte < 128 then byteCount = 1 elseif curByte >= 128 and curByte < 224 then byteCount = 2 elseif curByte >= 224 and curByte < 240 then byteCount = 3 elseif curByte >= 240 and curByte <= 247 then byteCount = 4 else break end i = i + byteCount count = count + 1 end return count end function string.firstToUpper(str) return (str:gsub("^%l", string.upper)) end function string.firstToLower(str) return (str:gsub("^%u", string.lower)) end function string.split(s, p) local rt = {} string.gsub( s, "[^" .. p .. "]+", function(w) table.insert(rt, w) end ) return rt end string.ltrim = function(s, c) local pattern = "^" .. (c or "%s") .. "+" return (string.gsub(s, pattern, "")) end string.rtrim = function(s, c) local pattern = (c or "%s") .. "+" .. "$" return (string.gsub(s, pattern, "")) end string.trim = function(s, c) return string.rtrim(string.ltrim(s, c), c) end -- 将字条串转换成字符数组 -- needChar为true时,返回字符数组,否则返回ASCII码数组 string.to_array = function(str, needChar) local list = {} for i = 1, math.huge do local ch = string.sub(str, i, i) if ch == "" then break end list[i] = needChar and ch or string.byte(ch) end return list end -- 最长公共子序列(longest common sequence) -- 返回lcs长度及s长度 string.lcs = function(s, c) local arrS = string.to_array(s) local arrC = string.to_array(c) local dp = {} for i = 1, #arrS do dp[i] = dp[i] or {} for j = 1, #arrC do local left = dp[i - 1] and dp[i - 1][j] or 0 local right = dp[i][j - 1] or 0 local up = dp[i - 1] and dp[i - 1][j - 1] or 0 local curCount = arrS[i] == arrC[j] and 1 or 0 dp[i][j] = math.max(left, right, up + curCount) end end return dp[#arrS][#arrC], #arrS end _tostring = tostring local function dump(obj) local cache = {} local getIndent, quoteStr, wrapKey, wrapVal, dumpObj, isLoop local pointerList = {} -- table检查:如果出现相同table指针,只打印指针地址,不打印内容,防止死循环 isLoop = function(val) if type(val) ~= "table" then return end local key = string.format("%s", val) if pointerList[key] then return true, key .. "(loop)" end pointerList[key] = true end getIndent = function(level) return string.rep("\t", level) end quoteStr = function(str) return '"' .. string.gsub(str, '"', '\\"') .. '"' end wrapKey = function(val, level) if type(val) == "number" then return "[" .. val .. "]" elseif type(val) == "string" then return "[" .. quoteStr(val) .. "]" elseif type(val) == "table" then if cache[val] then return "[" .. cache[val] .. "]" else return "[" .. dumpObj(val, level, ".") .. "]" end else return "[" .. tostring(val) .. "]" end end wrapVal = function(val, level, path) if type(val) == "table" then return dumpObj(val, level, path) elseif type(val) == "number" then return val elseif type(val) == "string" then return quoteStr(val) else return tostring(val) end end dumpObj = function(obj, level, path) if type(obj) ~= "table" then return wrapVal(obj) end local loop, val = isLoop(obj) if loop then return val end level = level + 1 if cache[obj] then return cache[obj] end cache[obj] = string.format('"%s"', path) local tokens = {} tokens[#tokens + 1] = "{" for k, v in pairs(obj) do if type(k) == "table" then tokens[#tokens + 1] = getIndent(level) .. wrapKey(k, level) .. " = " .. wrapVal(v, level, path .. cache[k] .. ".") .. "," else tokens[#tokens + 1] = getIndent(level) .. wrapKey(k, level) .. " = " .. wrapVal(v, level, path .. k .. ".") .. "," end end tokens[#tokens + 1] = getIndent(level - 1) .. "}" return table.concat(tokens, "\n") end return dumpObj(obj, 0, ".") end _tostring = tostring do local _tostring = tostring tostring = function(v) if type(v) == "table" then return dump(v) else return _tostring(v) end end end -- math扩展 do local _floor = math.floor math.floor = function(n, p) if p and p ~= 0 then local e = 10 ^ p return _floor(n * e) / e else return _floor(n) end end end math.round = function(n, p) local e = 10 ^ (p or 0) return math.floor(n * e + 0.5) / e end local rand = rand or math.random math.random = function(...) local args = {...} if type(args[1]) == "table" then return rand(args[1][1], args[1][2]) end return rand(...) end math.INT_MAX = math.floor(2 ^ 31 - 1) math.INT_MIN = math.floor(-2 ^ 31) -- lua面向对象扩展 function class(classname, super) local superType = type(super) local cls if superType ~= "function" and superType ~= "table" then superType = nil super = nil end if superType == "function" or (super and super.__ctype == 1) then -- inherited from native C++ Object cls = {} if superType == "table" then -- copy fields from super for k, v in pairs(super) do cls[k] = v end cls.__create = super.__create cls.super = super else cls.__create = super cls.ctor = function() end end cls.__cname = classname cls.__ctype = 1 function cls.new(...) local instance = cls.__create(...) -- copy fields from class to native object for k, v in pairs(cls) do instance[k] = v end instance.class = cls instance:ctor(...) return instance end else -- inherited from Lua Object if super then cls = {} setmetatable(cls, {__index = super}) cls.super = super else cls = { ctor = function() end } end cls.__cname = classname cls.__ctype = 2 -- lua function cls.new(...) local instance = setmetatable({}, {__index = cls}) instance.class = cls instance:ctor(...) return instance end end return cls end function iskindof(obj, classname) local t = type(obj) local mt if t == "table" then mt = getmetatable(obj) elseif t == "userdata" then mt = tolua.getpeer(obj) end while mt do if mt.__cname == classname then return true end mt = mt.super end return false end