394 lines
9.8 KiB
Lua
394 lines
9.8 KiB
Lua
|
function table.isEmpty(t)
|
|||
|
if type(t) ~= "table" then return true end
|
|||
|
return next(t) == nil
|
|||
|
end
|
|||
|
|
|||
|
function table.random(t, o)
|
|||
|
if table.isEmpty(t) then return nil; end
|
|||
|
local c = table.getCount(t)
|
|||
|
if c == 1 then
|
|||
|
if o then return t[0], 0; end
|
|||
|
return t[1], 1;
|
|||
|
else
|
|||
|
local r = math.random(o and 0 or 1, c)
|
|||
|
return t[r], r;
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function table.insertonce(t, v)
|
|||
|
if table.hasItem(t, v) then return; end
|
|||
|
table.insert(t, v);
|
|||
|
end
|
|||
|
|
|||
|
--- 将一个数组解压缩成几个元素
|
|||
|
function table.unpackTable(Arr)
|
|||
|
if Arr == nil then return nil; end
|
|||
|
local f = function(...) return ... end
|
|||
|
return f(table.unpack(Arr))
|
|||
|
end
|
|||
|
|
|||
|
---获取表中所有的Key
|
|||
|
function table.getKeys(t)
|
|||
|
if type(t) ~= "table" then return {} end
|
|||
|
local keys = {}
|
|||
|
for k,v in pairs(t) do keys[#keys + 1] = k end
|
|||
|
return keys
|
|||
|
end
|
|||
|
|
|||
|
---获取表中是否有对应Key
|
|||
|
function table.hasKey(t, k)
|
|||
|
if type(t) ~= "table" then return false end
|
|||
|
for key, value in pairs(t) do
|
|||
|
if k == key then return true end
|
|||
|
end
|
|||
|
return false
|
|||
|
end
|
|||
|
|
|||
|
---获取对应元素的Index
|
|||
|
function table.getIndex(t, v)
|
|||
|
if type(t) ~= "table" then return nil end
|
|||
|
for index, value in pairs(t) do
|
|||
|
if value == v then return index end
|
|||
|
end
|
|||
|
return nil
|
|||
|
end
|
|||
|
|
|||
|
function table.removeKey(t, k)
|
|||
|
if t == nil then return nil end
|
|||
|
local v = t[k]
|
|||
|
t[k] = nil
|
|||
|
return v
|
|||
|
end
|
|||
|
|
|||
|
function table.getCount(t)
|
|||
|
if type(t) ~= "table" then return -1 end
|
|||
|
local Length = 0
|
|||
|
for i, v in pairs(t) do Length = Length + 1 end
|
|||
|
return Length
|
|||
|
end
|
|||
|
|
|||
|
function table.isTablesEqual(t1, ...)
|
|||
|
local tables = { ... }
|
|||
|
log_tree('tables = ', tables)
|
|||
|
for i, v in pairs(tables) do
|
|||
|
if type(v) ~= 'table' then return false end
|
|||
|
for c, d in pairs(v) do
|
|||
|
if t1[c] ~= d then return false end
|
|||
|
end
|
|||
|
end
|
|||
|
return true
|
|||
|
end
|
|||
|
|
|||
|
---按Value删除表中元素
|
|||
|
---@generic T
|
|||
|
---@param t table<int32, T>
|
|||
|
---@return T|table<int32, T>
|
|||
|
function table.removeValue(t, v, all)
|
|||
|
local rs = {};
|
|||
|
for i, c in pairs(t) do
|
|||
|
if c == v then
|
|||
|
table.insert(rs, i);
|
|||
|
if not all then break; end
|
|||
|
end
|
|||
|
end
|
|||
|
table.sort(rs, function(a, b) return a > b end)
|
|||
|
for i = #rs, 1, -1 do table.remove(t, rs[i]); end
|
|||
|
end
|
|||
|
|
|||
|
---@generic T
|
|||
|
---@param t table<int32, T>
|
|||
|
---@param func fun(o:T):bool
|
|||
|
function table.remove1(t, func)
|
|||
|
if type(func) ~= 'function' then return end
|
|||
|
local rks = {};
|
|||
|
for i, v in pairs(t) do
|
|||
|
if func(v) then table.insert(rks, i); end
|
|||
|
end
|
|||
|
for i = #rks, 1, -1 do t[rks[i]] = nil; end
|
|||
|
end
|
|||
|
|
|||
|
---@param t table 需要添加的值
|
|||
|
---@param k PlayerKey | any key
|
|||
|
---@param v any value
|
|||
|
function table.addTableNum(t, k, v, l)
|
|||
|
t[k] = t[k] == nil and v or t[k] + v;
|
|||
|
if l == nil then return t[k]; end
|
|||
|
|
|||
|
if v < 0 then
|
|||
|
if t[k] < l then t[k] = l; end
|
|||
|
else
|
|||
|
if t[k] > l then t[k] = l; end
|
|||
|
end
|
|||
|
return t[k]
|
|||
|
end
|
|||
|
|
|||
|
function table.hasValue(t, value)
|
|||
|
if t == nil then return false end
|
|||
|
for k, v in pairs(t) do
|
|||
|
if v == value then return true end
|
|||
|
end
|
|||
|
return false
|
|||
|
end
|
|||
|
|
|||
|
--- 检查 t 中是否全部拥有列表 tt 中的
|
|||
|
function table.hasValues(t, tt)
|
|||
|
if t == nil then return false end
|
|||
|
local rt = table.intersection(t, tt)
|
|||
|
return table.getCount(rt) == table.getCount(tt);
|
|||
|
end
|
|||
|
|
|||
|
--- 对两个表取交集
|
|||
|
---@generic T
|
|||
|
---@param t1 table<any, T>
|
|||
|
---@param t2 table<any, T>
|
|||
|
---@return table<any, T>
|
|||
|
function table.intersection(t1, t2)
|
|||
|
local ret = {};
|
|||
|
local set = {};
|
|||
|
for _, v in pairs(t1) do
|
|||
|
if set[v] == nil then
|
|||
|
set[v] = 1;
|
|||
|
else
|
|||
|
set[v] = set[v] + 1;
|
|||
|
end
|
|||
|
end
|
|||
|
for _, v in pairs(t2) do
|
|||
|
if set[v] and set[v] > 0 then
|
|||
|
table.insert(ret, v);
|
|||
|
set[v] = set[v] - 1;
|
|||
|
end
|
|||
|
end
|
|||
|
return ret;
|
|||
|
end
|
|||
|
|
|||
|
function table.Swap(t, i, k)
|
|||
|
if type(t) ~= "table" then return false end
|
|||
|
local temp = t[i]
|
|||
|
t[i] = t[k]
|
|||
|
t[k] = temp
|
|||
|
end
|
|||
|
|
|||
|
--- 打乱整个table 洗牌算法
|
|||
|
function table.Shuffle(t)
|
|||
|
if type(t) ~= "table" then return false end
|
|||
|
if table.isEmpty(t) then return false; end
|
|||
|
if table.getCount(t) == 1 then return true; end
|
|||
|
for i = 1, #t - 1 do
|
|||
|
local SwapIndex = math.random(i + 1, #t)
|
|||
|
table.Swap(t, i, SwapIndex)
|
|||
|
end
|
|||
|
return true
|
|||
|
end
|
|||
|
|
|||
|
function table.Rand(t)
|
|||
|
if type(t) ~= "table" or #t <= 0 then return nil end
|
|||
|
return t[math.random(#t)]
|
|||
|
end
|
|||
|
|
|||
|
---@generic K, V
|
|||
|
---@param t1 table<K, V>
|
|||
|
---@param t2 table<K, V>
|
|||
|
---@return bool
|
|||
|
function table.compare(t1, t2)
|
|||
|
if type(t1) == 'table' and type(t2) == 'table' then
|
|||
|
if table.getCount(t1) ~= table.getCount(t2) then return false; end
|
|||
|
local Same = false;
|
|||
|
for i, v in pairs(t1) do
|
|||
|
if type(v) == 'table' then
|
|||
|
if not table.compare(v, t2[i]) then
|
|||
|
return false;
|
|||
|
end
|
|||
|
else
|
|||
|
if v ~= t2[i] then
|
|||
|
return false;
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
else
|
|||
|
if t1 ~= t2 then return false; end
|
|||
|
end
|
|||
|
return true;
|
|||
|
end
|
|||
|
|
|||
|
---@generic T
|
|||
|
---@param t table<any, T>
|
|||
|
---@param c T
|
|||
|
function table.hasItem(t, c)
|
|||
|
for i, v in pairs(t) do
|
|||
|
if v == c then return true; end
|
|||
|
end
|
|||
|
return false;
|
|||
|
end
|
|||
|
|
|||
|
-- 拷贝table
|
|||
|
function table.DeepCopy(object)
|
|||
|
-- 已经复制过的table,key为复制源table,value为复制后的table
|
|||
|
-- 为了防止table中的某个属性为自身时出现死循环
|
|||
|
-- 避免本该是同一个table的属性,在复制时变成2个不同的table(内容同,但是地址关系和原来的不一样了)
|
|||
|
local lookup_table = {}
|
|||
|
local function _copy(o)
|
|||
|
if type(o) ~= 'table' then -- 非table类型都直接返回
|
|||
|
return o
|
|||
|
elseif lookup_table[o] then
|
|||
|
return lookup_table[o]
|
|||
|
end
|
|||
|
local new_table = {}
|
|||
|
lookup_table[o] = new_table
|
|||
|
for k, v in pairs(o) do new_table[_copy(k)] = _copy(v) end
|
|||
|
-- 这里直接拿mt来用是因为一般对table操作不会很粗暴的修改mt的相关内容
|
|||
|
return setmetatable(new_table, getmetatable(object))
|
|||
|
end
|
|||
|
return _copy(object)
|
|||
|
end
|
|||
|
|
|||
|
|
|||
|
function table.GetMaxValueResKey(t, fun)
|
|||
|
if fun == nil then fun = function(p1, p2) return p1 < p2 end end
|
|||
|
if type(t) ~= "table" or type(fun) ~= "function" or table.getCount(t) <= 0 then return end
|
|||
|
local res = nil
|
|||
|
for k, v in pairs(t) do
|
|||
|
if not res or fun(t[res], v) then res = k end
|
|||
|
end
|
|||
|
return res
|
|||
|
end
|
|||
|
|
|||
|
function table.find(t, val)
|
|||
|
if type(t) ~= "table" then return nil end
|
|||
|
for k, v in pairs(t) do
|
|||
|
if v == val then return k end
|
|||
|
end
|
|||
|
return nil
|
|||
|
end
|
|||
|
|
|||
|
function table.GetMaxValue(t)
|
|||
|
if type(t) ~= "table" then return nil end
|
|||
|
local Res = nil
|
|||
|
for k, v in pairs(t) do
|
|||
|
if Res == nil then Res = v
|
|||
|
elseif Res < v then Res = v
|
|||
|
end
|
|||
|
end
|
|||
|
return Res
|
|||
|
end
|
|||
|
|
|||
|
---@generic T, U
|
|||
|
---@param t T
|
|||
|
---@param f string|fun(t: T, ...:U):any?
|
|||
|
---@vararg U
|
|||
|
function table.func(t, f, ...)
|
|||
|
if t ~= nil then
|
|||
|
if type(f) == 'function' then
|
|||
|
return f(t, ...);
|
|||
|
elseif type(f) == 'string' then
|
|||
|
if t[f] ~= nil then
|
|||
|
return table.func(t, t[f], ...);
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
-- 递归的向下找到对应的值,仅限第一个
|
|||
|
function table.getValue(t, k, isNest)
|
|||
|
for i, v in pairs(t) do
|
|||
|
if i == k then return v; end
|
|||
|
if isNest then
|
|||
|
if type(v) == 'table' then return table.getValue(v, k, isNest); end
|
|||
|
end
|
|||
|
end
|
|||
|
return nil;
|
|||
|
end
|
|||
|
|
|||
|
--- 查看是否含有函数
|
|||
|
function table.hasFunc(t, f)
|
|||
|
if type(f) == 'function' then return true; end
|
|||
|
if type(f) == 'string' then
|
|||
|
if t ~= nil then
|
|||
|
return type(t[f]) == 'function';
|
|||
|
end
|
|||
|
end
|
|||
|
return false;
|
|||
|
end
|
|||
|
|
|||
|
-- log输出格式化
|
|||
|
local function logPrint(str)
|
|||
|
str = os.date("\nLog output date: %Y-%m-%d %H:%M:%S \n", os.time()) .. str
|
|||
|
print(str)
|
|||
|
end
|
|||
|
|
|||
|
-- key值格式化
|
|||
|
local function formatKey(key)
|
|||
|
local t = type(key)
|
|||
|
if t == "number" then
|
|||
|
return "[" .. key .. "]"
|
|||
|
elseif t == "string" then
|
|||
|
local n = tonumber(key)
|
|||
|
if n then return "[" .. key .. "]" end
|
|||
|
end
|
|||
|
return key
|
|||
|
end
|
|||
|
|
|||
|
-- 栈
|
|||
|
local function newStack()
|
|||
|
local stack = { tableList = {} }
|
|||
|
function stack:push(t) table.insert(self.tableList, t) end
|
|||
|
function stack:pop() return table.remove(self.tableList) end
|
|||
|
function stack:contains(t)
|
|||
|
for _, v in ipairs(self.tableList) do
|
|||
|
if v == t then return true end
|
|||
|
end
|
|||
|
return false
|
|||
|
end
|
|||
|
return stack
|
|||
|
end
|
|||
|
|
|||
|
-- 输出打印table表 函数
|
|||
|
function table.printTable(...)
|
|||
|
local args = {...}
|
|||
|
|
|||
|
local function table2String(temp, stack, t, depth)
|
|||
|
stack:push(t)
|
|||
|
if type(depth) == "number" then
|
|||
|
depth = depth + 1
|
|||
|
else
|
|||
|
depth = 1
|
|||
|
end
|
|||
|
local indent = ""
|
|||
|
for i = 1, depth do indent = indent .. " " end
|
|||
|
for k, v in pairs(t) do
|
|||
|
local key = tostring(k)
|
|||
|
local typeV = type(v)
|
|||
|
if typeV == "table" then
|
|||
|
if key ~= "__valuePrototype" then
|
|||
|
if stack:contains(v) then
|
|||
|
table.insert(temp, indent .. formatKey(key) .. " = {检测到循环引用!},\n")
|
|||
|
else
|
|||
|
table.insert(temp, indent .. formatKey(key) .. " = {\n")
|
|||
|
table2String(temp, stack, v, depth)
|
|||
|
table.insert(temp, indent .. "},\n")
|
|||
|
end
|
|||
|
end
|
|||
|
elseif typeV == "string" then
|
|||
|
table.insert(temp, string.format("%s%s = \"%s\",\n", indent, formatKey(key), tostring(v)))
|
|||
|
else
|
|||
|
table.insert(temp, string.format("%s%s = %s,\n", indent, formatKey(key), tostring(v)))
|
|||
|
end
|
|||
|
end
|
|||
|
stack:pop()
|
|||
|
end
|
|||
|
|
|||
|
for k, v in pairs(args) do
|
|||
|
local root = v
|
|||
|
if type(root) == "table" then
|
|||
|
local temp = {"------------------------ printTable start ------------------------\n",
|
|||
|
"local tableValue" .. " = {\n"}
|
|||
|
local stack = newStack()
|
|||
|
|
|||
|
table2String(temp, stack, root)
|
|||
|
table.insert(temp, "}\n------------------------- printTable end -------------------------")
|
|||
|
logPrint(table.concat(temp))
|
|||
|
else
|
|||
|
logPrint("----------------------- printString start ------------------------\n" .. tostring(root) ..
|
|||
|
"\n------------------------ printString end -------------------------")
|
|||
|
end
|
|||
|
end
|
|||
|
end
|