直接放入Zframework文件
This commit is contained in:
463
Zframework/tableExtend.lua
Normal file
463
Zframework/tableExtend.lua
Normal file
@@ -0,0 +1,463 @@
|
||||
local rnd=math.random
|
||||
local min,max=math.min,math.max
|
||||
local find=string.find
|
||||
local ins,rem=table.insert,table.remove
|
||||
local next,type=next,type
|
||||
local TABLE={}
|
||||
|
||||
-----------------------[Making Tables]------------------------
|
||||
-- Get a new filled table
|
||||
function TABLE.new(val,count)
|
||||
local L={}
|
||||
for i=1,count do
|
||||
L[i]=val
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
-- Get a copy of [1~#] elements
|
||||
function TABLE.shift(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for i=1,#org do
|
||||
if type(org[i])=='table' and depth>0 then
|
||||
L[i]=TABLE.shift(org[i],depth-1)
|
||||
else
|
||||
L[i]=org[i]
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
-- Get a full copy of a table, depth=how many layers will be recreate, default to inf
|
||||
function TABLE.copy(org,depth)
|
||||
if not depth then depth=1e99 end
|
||||
local L={}
|
||||
for k,v in next,org do
|
||||
if type(v)=='table' and depth>0 then
|
||||
L[k]=TABLE.copy(v,depth-1)
|
||||
else
|
||||
L[k]=v
|
||||
end
|
||||
end
|
||||
return L
|
||||
end
|
||||
|
||||
-- Connect [1~#] elements of new to the end of org
|
||||
function TABLE.connect(org,new)
|
||||
local l0=#org
|
||||
for i=1,#new do
|
||||
org[l0+i]=new[i]
|
||||
end
|
||||
return org
|
||||
end
|
||||
|
||||
-- Get a table of two lists connected
|
||||
function TABLE.combine(L1,L2)
|
||||
local l={}
|
||||
local l0=#L1
|
||||
for i=1,l0 do l[i]=L1[i] end
|
||||
for i=1,#L2 do l[l0+i]=L2[i] end
|
||||
return l
|
||||
end
|
||||
|
||||
----------------------[Modifying Tables]----------------------
|
||||
|
||||
-- For all things in new, push to old
|
||||
function TABLE.cover(new,old)
|
||||
for k,v in next,new do
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
|
||||
-- For all things in new, push to old
|
||||
function TABLE.coverR(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)=='table' and type(old[k])=='table' then
|
||||
TABLE.coverR(v,old[k])
|
||||
else
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- For all things in org, delete them if it's in sub
|
||||
function TABLE.subtract(org,sub)
|
||||
for _,v in next,sub do
|
||||
while true do
|
||||
local p=TABLE.search(org,v)
|
||||
if p then
|
||||
rem(org,p)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- For all things in new if same type in old, push to old
|
||||
function TABLE.update(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)==type(old[k]) then
|
||||
if type(v)=='table' then
|
||||
TABLE.update(v,old[k])
|
||||
else
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- For all things in new if no val in old, push to old
|
||||
function TABLE.complete(new,old)
|
||||
for k,v in next,new do
|
||||
if type(v)=='table' then
|
||||
if old[k]==nil then old[k]={} end
|
||||
TABLE.complete(v,old[k])
|
||||
elseif old[k]==nil then
|
||||
old[k]=v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------[Removing Table Values]--------------------
|
||||
|
||||
-- Pop & return random [1~#] of table
|
||||
function TABLE.popRandom(t)
|
||||
local l=#t
|
||||
if l>0 then
|
||||
local r=rnd(l)
|
||||
r,t[r]=t[r],t[l]
|
||||
t[l]=nil
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove [1~#] of table
|
||||
function TABLE.cut(G)
|
||||
for i=1,#G do
|
||||
G[i]=nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Clear table
|
||||
function TABLE.clear(G)
|
||||
for k in next,G do
|
||||
G[k]=nil
|
||||
end
|
||||
end
|
||||
|
||||
--------------------[Handling duplicates]---------------------
|
||||
|
||||
-- Remove duplicated value of [1~#]
|
||||
function TABLE.trimDuplicate(org)
|
||||
local cache={}
|
||||
for i=1,#org,-1 do
|
||||
if cache[org[i]] then
|
||||
rem(org,i)
|
||||
else
|
||||
cache[org[i]]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Discard duplicated value
|
||||
function TABLE.remDuplicate(org)
|
||||
local cache={}
|
||||
for k,v in next,org do
|
||||
if cache[v] then
|
||||
org[k]=nil
|
||||
else
|
||||
cache[v]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Run length encoder. Input must be a list containing non-nil value(s).
|
||||
Example:
|
||||
- Input: {1, 1, 2, 2, 2, 1}
|
||||
- Output: {{1, 2}, {2, 3}, {1, 1}}
|
||||
- This means: "Two 1's in a row", "Three 2's in a row", "One 1 in a row"
|
||||
]]
|
||||
function TABLE.RLE(org)
|
||||
local output={}
|
||||
local cur=nil
|
||||
local count=0
|
||||
|
||||
for i=1,#org do
|
||||
local item=org[i]
|
||||
|
||||
if item==cur then
|
||||
count=count+1
|
||||
else
|
||||
if cur then
|
||||
ins(output,{cur,count})
|
||||
end
|
||||
cur=item
|
||||
count=1
|
||||
end
|
||||
end
|
||||
|
||||
if cur then
|
||||
ins(output,{cur,count})
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
----------------------[Reversing Tables]----------------------
|
||||
|
||||
-- Reverse [1~#]
|
||||
function TABLE.reverse(org)
|
||||
local l=#org
|
||||
for i=1,math.floor(l/2) do
|
||||
org[i],org[l+1-i]=org[l+1-i],org[i]
|
||||
end
|
||||
end
|
||||
|
||||
----------------------[Table Comparison]----------------------
|
||||
|
||||
-- Check if tow list have same elements
|
||||
function TABLE.compare(a,b)
|
||||
if #a~=#b then return false end
|
||||
if a==b then return true end
|
||||
for i=1,#a do
|
||||
if a[i]~=b[i] then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check if tow table have same elements
|
||||
function TABLE.equal(a,b)
|
||||
if #a~=#b then return false end
|
||||
if a==b then return true end
|
||||
for k,v in next,a do
|
||||
if b[k]~=v then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
----------------------[Table Operations]----------------------
|
||||
|
||||
-- Find value in [1~#], like string.find
|
||||
function TABLE.find(t,val,start)
|
||||
for i=start or 1,#t do if t[i]==val then return i end end
|
||||
end
|
||||
|
||||
-- Get subset of table, like string.sub
|
||||
function TABLE.sub(t,i,j)
|
||||
local subTable={}
|
||||
for k=max(i,1),(j and min(j,#t) or #t) do
|
||||
subTable[k-i+1]=t[k]
|
||||
end
|
||||
return subTable
|
||||
end
|
||||
|
||||
-- Replace value in [1~#], like string.gsub
|
||||
function TABLE.gsub(t,v_old,v_new,count,start)
|
||||
if not start then start=1 end
|
||||
if not count then count=1e99 end
|
||||
while t[start] and count>0 do
|
||||
if t[start]==v_old then
|
||||
t[start]=v_new
|
||||
count=count-1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return next value of [1~#] (by value)
|
||||
function TABLE.next(t,val)
|
||||
for i=1,#t do if t[i]==val then return t[i%#t+1] end end
|
||||
end
|
||||
|
||||
-- Find value in whole table
|
||||
function TABLE.search(t,val)
|
||||
for k,v in next,t do if v==val then return k end end
|
||||
end
|
||||
|
||||
-- Replace all value in t
|
||||
function TABLE.replace(t,v_old,v_new)
|
||||
for k,v in next,t do
|
||||
if v==v_old then
|
||||
t[k]=v_new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Re-index string value of a table
|
||||
function TABLE.reIndex(org)
|
||||
for k,v in next,org do
|
||||
if type(v)=='string' then
|
||||
org[k]=org[v]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return table where keys and values are swapped (useful for hashmap)
|
||||
function TABLE.kvSwap(t)
|
||||
local output={}
|
||||
for k,v in next,t do output[v]=k end
|
||||
return output
|
||||
end
|
||||
|
||||
--[[
|
||||
Extracts a value from each sub-table in table.
|
||||
Example input: ({{name='A'},{name='B'},{name='C'}}, 'name')
|
||||
Output: {'A','B'}
|
||||
]]
|
||||
function TABLE.extract(t,keyName)
|
||||
local output={}
|
||||
for k,v in next,t do output[k]=v[keyName] end
|
||||
return output
|
||||
end
|
||||
|
||||
-- Get element count of table
|
||||
function TABLE.getSize(t)
|
||||
local size=0
|
||||
for _ in next,t do size=size+1 end
|
||||
return size
|
||||
end
|
||||
|
||||
-----------------------[Table Rotation]-----------------------
|
||||
|
||||
-- Copy a rotated matrix table
|
||||
function TABLE.rotate(cb,dir)
|
||||
local icb={}
|
||||
if dir=='R' then-- Rotate CW
|
||||
for y=1,#cb[1] do
|
||||
icb[y]={}
|
||||
for x=1,#cb do
|
||||
icb[y][x]=cb[x][#cb[1]-y+1]
|
||||
end
|
||||
end
|
||||
elseif dir=='L' then-- Rotate CCW
|
||||
for y=1,#cb[1] do
|
||||
icb[y]={}
|
||||
for x=1,#cb do
|
||||
icb[y][x]=cb[#cb-x+1][y]
|
||||
end
|
||||
end
|
||||
elseif dir=='F' then-- Rotate 180 degree
|
||||
for y=1,#cb do
|
||||
icb[y]={}
|
||||
for x=1,#cb[1] do
|
||||
icb[y][x]=cb[#cb-y+1][#cb[1]-x+1]
|
||||
end
|
||||
end
|
||||
end
|
||||
return icb
|
||||
end
|
||||
|
||||
----------------------[Table Functions]-----------------------
|
||||
|
||||
-- Return a function that return a value of table
|
||||
function TABLE.func_getVal(t,k)
|
||||
return function() return t[k] end
|
||||
end
|
||||
|
||||
-- Return a function that reverse a value of table
|
||||
function TABLE.func_revVal(t,k)
|
||||
return function() t[k]=not t[k] end
|
||||
end
|
||||
|
||||
-- Return a function that set a value of table
|
||||
function TABLE.func_setVal(t,k)
|
||||
return function(v) t[k]=v end
|
||||
end
|
||||
|
||||
-------------------------[Table Dump]-------------------------
|
||||
|
||||
-- Dump a simple lua table (no whitespaces)
|
||||
do-- function TABLE.dumpDeflate(L,t)
|
||||
local function dump(L)
|
||||
if type(L)~='table' then return end
|
||||
local s='{'
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=='number' then
|
||||
if k==count then
|
||||
k=''
|
||||
count=count+1
|
||||
else
|
||||
k='['..k..']='
|
||||
end
|
||||
elseif T=='string' then
|
||||
if find(k,'[^0-9a-zA-Z_]') then
|
||||
k='[\''..k..'\']='
|
||||
else
|
||||
k=k..'='
|
||||
end
|
||||
elseif T=='boolean' then k='['..k..']='
|
||||
else error("Error key type!")
|
||||
end
|
||||
T=type(v)
|
||||
if T=='number' then v=tostring(v)
|
||||
elseif T=='string' then v='\''..v..'\''
|
||||
elseif T=='table' then v=dump(v)
|
||||
elseif T=='boolean' then v=tostring(v)
|
||||
else v='*'..tostring(v)
|
||||
end
|
||||
s=s..k..v..','
|
||||
end
|
||||
return s..'}'
|
||||
end
|
||||
TABLE.dumpDeflate=dump
|
||||
end
|
||||
|
||||
-- Dump a simple lua table
|
||||
do-- function TABLE.dump(L,t)
|
||||
local tabs=setmetatable({
|
||||
[0]='',
|
||||
'\t',
|
||||
},{__index=function(self,k)
|
||||
if k>=626 then error("Too many tabs!") end
|
||||
for i=#self+1,k do
|
||||
self[i]=self[i-1]..'\t'
|
||||
end
|
||||
return self[k]
|
||||
end})
|
||||
local function dump(L,t)
|
||||
local s='{\n'
|
||||
if not t then
|
||||
s='return {\n'
|
||||
t=1
|
||||
if type(L)~='table' then
|
||||
return
|
||||
end
|
||||
end
|
||||
local count=1
|
||||
for k,v in next,L do
|
||||
local T=type(k)
|
||||
if T=='number' then
|
||||
if k==count then
|
||||
k=''
|
||||
count=count+1
|
||||
else
|
||||
k='['..k..']='
|
||||
end
|
||||
elseif T=='string' then
|
||||
if find(k,'[^0-9a-zA-Z_]') then
|
||||
k='[\''..k..'\']='
|
||||
else
|
||||
k=k..'='
|
||||
end
|
||||
elseif T=='boolean' then k='['..k..']='
|
||||
else k='[\'*'..tostring(k)..'\']='
|
||||
end
|
||||
T=type(v)
|
||||
if T=='number' then v=tostring(v)
|
||||
elseif T=='string' then v='\''..v..'\''
|
||||
elseif T=='table' then v=dump(v,t+1)
|
||||
elseif T=='boolean' then v=tostring(v)
|
||||
else v='*'..tostring(v)
|
||||
end
|
||||
s=s..tabs[t]..k..v..',\n'
|
||||
end
|
||||
return s..tabs[t-1]..'}'
|
||||
end
|
||||
TABLE.dump=dump
|
||||
end
|
||||
|
||||
return TABLE
|
||||
Reference in New Issue
Block a user