table.lua

main 288 lines · 5.9 KB Raw
Alex Alex Commit Client Upload Part 2 19/10/2026 00:06
1-- @docclass table
2
3function table.dump(t, depth)
4 if not depth then depth = 0 end
5 for k,v in pairs(t) do
6 str = (' '):rep(depth * 2) .. k .. ': '
7 if type(v) ~= "table" then
8 print(str .. tostring(v))
9 else
10 print(str)
11 table.dump(v, depth+1)
12 end
13 end
14end
15
16function table.clear(t)
17 for k,v in pairs(t) do
18 t[k] = nil
19 end
20end
21
22function table.copy(t)
23 local res = {}
24 for k,v in pairs(t) do
25 res[k] = v
26 end
27 return res
28end
29
30function table.recursivecopy(t)
31 local res = {}
32 for k,v in pairs(t) do
33 if type(v) == "table" then
34 res[k] = table.recursivecopy(v)
35 else
36 res[k] = v
37 end
38 end
39 return res
40end
41
42function table.selectivecopy(t, keys)
43 local res = { }
44 for i,v in ipairs(keys) do
45 res[v] = t[v]
46 end
47 return res
48end
49
50function table.merge(t, src)
51 for k,v in pairs(src) do
52 t[k] = v
53 end
54end
55
56function table.find(t, value, lowercase)
57 for k,v in pairs(t) do
58 if lowercase and type(value) == 'string' and type(v) == 'string' then
59 if v:lower() == value:lower() then return k end
60 end
61 if v == value then return k end
62 end
63end
64
65function table.findbykey(t, key, lowercase)
66 for k,v in pairs(t) do
67 if lowercase and type(key) == 'string' and type(k) == 'string' then
68 if k:lower() == key:lower() then return v end
69 end
70 if k == key then return v end
71 end
72end
73
74function table.contains(t, value, lowercase)
75 return table.find(t, value, lowercase) ~= nil
76end
77
78function table.findkey(t, key)
79 if t and type(t) == 'table' then
80 for k,v in pairs(t) do
81 if k == key then return k end
82 end
83 end
84end
85
86function table.haskey(t, key)
87 return table.findkey(t, key) ~= nil
88end
89
90function table.removevalue(t, value)
91 for k,v in pairs(t) do
92 if v == value then
93 table.remove(t, k)
94 return true
95 end
96 end
97 return false
98end
99
100function table.popvalue(value)
101 local index = nil
102 for k,v in pairs(t) do
103 if v == value or not value then
104 index = k
105 end
106 end
107 if index then
108 table.remove(t, index)
109 return true
110 end
111 return false
112end
113
114function table.compare(t, other)
115 if #t ~= #other then return false end
116 for k,v in pairs(t) do
117 if v ~= other[k] then return false end
118 end
119 return true
120end
121
122function table.empty(t)
123 if t and type(t) == 'table' then
124 return next(t) == nil
125 end
126 return true
127end
128
129function table.permute(t, n, count)
130 n = n or #t
131 for i=1,count or n do
132 local j = math.random(i, n)
133 t[i], t[j] = t[j], t[i]
134 end
135 return t
136end
137
138function table.findbyfield(t, fieldname, fieldvalue)
139 for _i,subt in pairs(t) do
140 if subt[fieldname] == fieldvalue then
141 return subt
142 end
143 end
144 return nil
145end
146
147function table.size(t)
148 local size = 0
149 for i, n in pairs(t) do
150 size = size + 1
151 end
152
153 return size
154end
155
156function table.tostring(t)
157 local maxn = #t
158 local str = ""
159 for k,v in pairs(t) do
160 v = tostring(v)
161 if k == maxn and k ~= 1 then
162 str = str .. " and " .. v
163 elseif maxn > 1 and k ~= 1 then
164 str = str .. ", " .. v
165 else
166 str = str .. " " .. v
167 end
168 end
169 return str
170end
171
172function table.collect(t, func)
173 local res = {}
174 for k,v in pairs(t) do
175 local a,b = func(k,v)
176 if a and b then
177 res[a] = b
178 elseif a ~= nil then
179 table.insert(res,a)
180 end
181 end
182 return res
183end
184
185function table.equals(t, comp)
186 if type(t) == "table" and type(comp) == "table" then
187 for k,v in pairs(t) do
188 if v ~= comp[k] then return false end
189 end
190 end
191 return true
192end
193
194function table.equal(t1,t2,ignore_mt)
195 local ty1 = type(t1)
196 local ty2 = type(t2)
197 if ty1 ~= ty2 then return false end
198 -- non-table types can be directly compared
199 if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
200 -- as well as tables which have the metamethod __eq
201 local mt = getmetatable(t1)
202 if not ignore_mt and mt and mt.__eq then return t1 == t2 end
203 for k1,v1 in pairs(t1) do
204 local v2 = t2[k1]
205 if v2 == nil or not table.equal(v1,v2) then return false end
206 end
207 for k2,v2 in pairs(t2) do
208 local v1 = t1[k2]
209 if v1 == nil or not table.equal(v1,v2) then return false end
210 end
211 return true
212end
213
214function table.isList(t)
215 local size = #t
216 return table.size(t) == size and size > 0
217end
218
219function table.isStringList(t)
220 if not table.isList(t) then return false end
221 for k,v in ipairs(t) do
222 if type(v) ~= 'string' then
223 return false
224 end
225 end
226 return true
227end
228
229function table.isStringPairList(t)
230 if not table.isList(t) then return false end
231 for k,v in ipairs(t) do
232 if type(v) ~= 'table' or #v ~= 2 or type(v[1]) ~= 'string' or type(v[2]) ~= 'string' then
233 return false
234 end
235 end
236 return true
237end
238
239function table.encodeStringPairList(t)
240 local ret = ""
241 for k,v in ipairs(t) do
242 if v[2]:find("\n") then
243 ret = ret .. v[1] .. ":[[\n" .. v[2] .. "\n]]\n"
244 else
245 ret = ret .. v[1] .. ":" .. v[2] .. "\n"
246 end
247 end
248 return ret
249end
250
251function table.decodeStringPairList(l)
252 local ret = {}
253 local r = regexMatch(l, "(?:^|\\n)([^:^\n]{1,20}):?(.*)(?:$|\\n)")
254 local multiline = ""
255 local multilineKey = ""
256 local multilineActive = false
257 for k,v in ipairs(r) do
258 if multilineActive then
259 local endPos = v[1]:find("%]%]")
260 if endPos then
261 if endPos > 1 then
262 table.insert(ret, {multilineKey, multiline .. "\n" .. v[1]:sub(1, endPos - 1)})
263 else
264 table.insert(ret, {multilineKey, multiline})
265 end
266 multilineActive = false
267 multiline = ""
268 multilineKey = ""
269 else
270 if multiline:len() == 0 then
271 multiline = v[1]
272 else
273 multiline = multiline .. "\n" .. v[1]
274 end
275 end
276 else
277 local bracketPos = v[3]:find("%[%[")
278 if bracketPos == 1 then -- multiline begin
279 multiline = v[3]:sub(bracketPos + 2)
280 multilineActive = true
281 multilineKey = v[2]
282 elseif v[2]:len() > 0 and v[3]:len() > 0 then
283 table.insert(ret, {v[2], v[3]})
284 end
285 end
286 end
287 return ret
288end
Top