188 lines
2.8 KiB
Lua
188 lines
2.8 KiB
Lua
local default_cmp = futil.math.cmp
|
|
|
|
futil.table = {}
|
|
|
|
function futil.table.set_all(t1, t2)
|
|
for k, v in pairs(t2) do
|
|
t1[k] = v
|
|
end
|
|
return t1
|
|
end
|
|
|
|
function futil.table.compose(t1, t2)
|
|
local t = table.copy(t1)
|
|
futil.table.set_all(t, t2)
|
|
return t
|
|
end
|
|
|
|
function futil.table.pairs_by_value(t, cmp)
|
|
cmp = cmp or default_cmp
|
|
local s = {}
|
|
for k, v in pairs(t) do
|
|
table.insert(s, { k, v })
|
|
end
|
|
|
|
table.sort(s, function(a, b)
|
|
return cmp(a[2], b[2])
|
|
end)
|
|
|
|
local i = 0
|
|
return function()
|
|
i = i + 1
|
|
local v = s[i]
|
|
if v then
|
|
return unpack(v)
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function futil.table.pairs_by_key(t, cmp)
|
|
cmp = cmp or default_cmp
|
|
local s = {}
|
|
for k, v in pairs(t) do
|
|
table.insert(s, { k, v })
|
|
end
|
|
|
|
table.sort(s, function(a, b)
|
|
return cmp(a[1], b[1])
|
|
end)
|
|
|
|
local i = 0
|
|
return function()
|
|
i = i + 1
|
|
local v = s[i]
|
|
if v then
|
|
return unpack(v)
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function futil.table.size(t)
|
|
local size = 0
|
|
for _ in pairs(t) do
|
|
size = size + 1
|
|
end
|
|
return size
|
|
end
|
|
|
|
function futil.table.is_empty(t)
|
|
return next(t) == nil
|
|
end
|
|
|
|
function futil.table.count_elements(t)
|
|
local counts = {}
|
|
for _, item in ipairs(t) do
|
|
counts[item] = (counts[item] or 0) + 1
|
|
end
|
|
return counts
|
|
end
|
|
|
|
function futil.table.sets_intersect(set1, set2)
|
|
for k in pairs(set1) do
|
|
if set2[k] then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function futil.table.iterate(t)
|
|
local i = 0
|
|
return function()
|
|
i = i + 1
|
|
return t[i]
|
|
end
|
|
end
|
|
|
|
function futil.table.reversed(t)
|
|
local len = #t
|
|
local reversed = {}
|
|
|
|
for i = len, 1, -1 do
|
|
reversed[len - i + 1] = t[i]
|
|
end
|
|
|
|
return reversed
|
|
end
|
|
|
|
function futil.table.contains(t, value)
|
|
for _, v in ipairs(t) do
|
|
if v == value then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function futil.table.keys(t)
|
|
local keys = {}
|
|
for key in pairs(t) do
|
|
keys[#keys + 1] = key
|
|
end
|
|
return keys
|
|
end
|
|
|
|
function futil.table.ikeys(t)
|
|
local key
|
|
return function()
|
|
key = next(t, key)
|
|
return key
|
|
end
|
|
end
|
|
|
|
function futil.table.values(t)
|
|
local values = {}
|
|
for _, value in pairs(t) do
|
|
values[#values + 1] = value
|
|
end
|
|
return values
|
|
end
|
|
|
|
function futil.table.sort_keys(t, cmp)
|
|
local keys = futil.table.keys(t)
|
|
table.sort(keys, cmp)
|
|
return keys
|
|
end
|
|
|
|
-- https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
|
|
function futil.table.shuffle(t, rnd)
|
|
rnd = rnd or math.random
|
|
for i = #t, 2, -1 do
|
|
local j = rnd(i)
|
|
t[i], t[j] = t[j], t[i]
|
|
end
|
|
return t
|
|
end
|
|
|
|
local function swap(t, i, j)
|
|
t[i], t[j] = t[j], t[i]
|
|
end
|
|
|
|
futil.table.swap = swap
|
|
|
|
function futil.table.get(t, key, default)
|
|
local value = t[key]
|
|
if value == nil then
|
|
return default
|
|
end
|
|
return value
|
|
end
|
|
|
|
function futil.table.setdefault(t, key, default)
|
|
local value = t[key]
|
|
if value == nil then
|
|
t[key] = default
|
|
return default
|
|
end
|
|
return value
|
|
end
|
|
|
|
function futil.table.pack(...)
|
|
return { n = select("#", ...), ... }
|
|
end
|