Table: Fix rpairs, unique and values, formatting

This commit is contained in:
Lars Mueller 2020-12-12 16:15:26 +01:00
parent 9f5de0d3a6
commit 43f59aa329

240
table.lua

@ -39,7 +39,6 @@ function shuffle(table)
return table return table
end end
-- TODO circular equals
function equals_noncircular(table_1, table_2) function equals_noncircular(table_1, table_2)
local is_equal = table_1 == table_2 local is_equal = table_1 == table_2
if is_equal or type(table_1) ~= "table" or type(table_2) ~= "table" then if is_equal or type(table_1) ~= "table" or type(table_2) ~= "table" then
@ -146,45 +145,57 @@ function is_empty(table)
return next(table) == nil return next(table) == nil
end end
function foreach(t, func) function foreach(table, func)
for k, v in pairs(t) do for k, v in pairs(table) do
func(k, v) func(k, v)
end end
end end
function foreach_value(t, func) function foreach_value(table, func)
for _, v in pairs(t) do for _, v in pairs(table) do
func(v) func(v)
end end
end end
function foreach_key(t, func) function call(table, ...)
for k, _ in pairs(t) do for _, func in pairs(table) do
func(k) func(...)
end end
end end
function map(t, func) function icall(table, ...)
for k, v in pairs(t) do for _, func in ipairs(table) do
t[k]=func(v) func(...)
end end
return t
end end
function map_keys(tab, func) function foreach_key(table, func)
for key, _ in pairs(table) do
func(key)
end
end
function map(table, func)
for key, value in pairs(table) do
table[key] = func(value)
end
return table
end
function map_keys(table, func)
local new_tab = {} local new_tab = {}
for key, value in pairs(tab) do for key, value in pairs(table) do
new_tab[func(key)] = value new_tab[func(key)] = value
end end
return new_tab return new_tab
end end
function process(t, func) function process(table, func)
local r={} local results = {}
for k, v in pairs(t) do for key, value in pairs(table) do
table.insert(r, func(k,v)) table.insert(results, func(key,value))
end end
return r return results
end end
function call(funcs, ...) function call(funcs, ...)
@ -204,160 +215,171 @@ end
contains = find contains = find
function difference(table1, table2) function difference(table, other_table)
local result={}
for k, v in pairs(table2) do
local v2=table1[v]
if v2~=v then
result[k]=v
end
end
return result
end
function add_all(dst, new)
for key, value in pairs(new) do
dst[key] = value
end
return dst
end
function complete(dst, new)
for key, value in pairs(new) do
if dst[key] == nil then
dst[key] = value
end
end
return dst
end
function merge_tables(table1, table2)
return add_all(copy(table1), table2)
end
union = merge_tables
function intersection(t1, t2)
local result = {} local result = {}
for key, value in pairs(t1) do for key, value in pairs(other_table) do
if t2[key] then if table[value] ~= value then
result[key] = value result[key] = value
end end
end end
return result return result
end end
function append(t1, t2) function add_all(table, additions)
local l=#t1 for key, value in pairs(additions) do
for k, v in ipairs(t2) do table[key] = value
t1[l+k]=v
end end
return t1 return table
end end
function keys(t) function complete(table, completions)
for key, value in pairs(completions) do
if table[key] == nil then
table[key] = value
end
end
return table
end
function deepcomplete(table, completions)
for key, value in pairs(completions) do
if table[key] == nil then
table[key] = value
elseif type(table[key]) == "table" and type(value) == "table" then
deepcomplete(table[key], value)
end
end
return table
end
function merge_tables(table, other_table)
return add_all(copy(table), other_table)
end
union = merge_tables
function intersection(table, other_table)
local result = {}
for key, value in pairs(table) do
if other_table[key] then
result[key] = value
end
end
return result
end
function append(table, other_table)
local length = #table
for index, value in ipairs(other_table) do
table[length + index] = value
end
return table
end
function keys(table)
local keys = {} local keys = {}
for key, _ in pairs(t) do for key, _ in pairs(table) do
table.insert(keys, key) keys[#keys + 1] = key
end end
return keys return keys
end end
function values(t) function values(table)
local values = {} local values = {}
for key, _ in pairs(t) do for _, value in pairs(table) do
table.insert(values, key) values[#values + 1] = value
end end
return values return values
end end
function flip(table) function flip(table)
local flipped = {} local flipped = {}
for key, val in pairs(table) do for key, value in pairs(table) do
flipped[val] = key flipped[value] = key
end end
return flipped return flipped
end end
function set(table) function set(table)
local flipped = {} local flipped = {}
for _, val in pairs(table) do for _, value in pairs(table) do
flipped[val] = true flipped[value] = true
end end
return flipped return flipped
end end
function unique(table) function unique(table)
local lookup = {} local lookup = {}
for val in ipairs(table) do for _, value in pairs(table) do
lookup[val] = true lookup[value] = true
end end
return keys(lookup) return keys(lookup)
end end
function rpairs(t) function rpairs(table)
local i = #t local index = #table
return function () return function()
if i >= 1 then if index >= 1 then
local v=t[i] local value = table[index]
i = i-1 index = index - 1
if v then if value ~= nil then
return i+1, v return index + 1, value
end end
end end
end end
end end
function best_value(table, is_better_fnc) function best_value(table, is_better_func)
if not table or not is_better_fnc then local best = next(table)
return nil if best == nil then
return
end end
local l=#table local candidate = best
if l==0 then while true do
return nil candidate = next(table, candidate)
end if candidate == nil then
local m=table[1] return best
for i=2, l do end
local v=table[i] if is_better_func(candidate, best) then
if is_better_fnc(v, m) then best = candidate
m=v
end end
end end
return m error()
end end
function min(table) function min(table)
return best_value(table, function(v, m) return v < m end) return best_value(table, function(value, other_value) return value < other_value end)
end end
function max(table) function max(table)
return best_value(table, function(v, m) return v > m end) return best_value(table, function(value, other_value) return value > other_value end)
end end
function default_comparator(a, b) function default_comparator(value, other_value)
if a == b then if value == other_value then
return 0 return 0
end end
if a > b then if value > other_value then
return 1 return 1
end end
return -1 return -1
end end
--> index if element found
--> -index for insertion if not found
function binary_search_comparator(comparator) function binary_search_comparator(comparator)
-- if found, returns index; if not found, returns -index for insertion
return function(list, value) return function(list, value)
local min, max = 1, #list local min, max = 1, #list
while min <= max do while min <= max do
local pivot = min + math.floor((max-min)/2) local pivot = min + math.floor((max - min) / 2)
local element = list[pivot] local element = list[pivot]
local compared = comparator(value, element) local compared = comparator(value, element)
if compared == 0 then if compared == 0 then
return pivot return pivot
elseif compared > 0 then elseif compared > 0 then
min = pivot+1 min = pivot + 1
else else
max = pivot-1 max = pivot - 1
end end
end end
return -min return -min
@ -366,18 +388,18 @@ end
binary_search = binary_search_comparator(default_comparator) binary_search = binary_search_comparator(default_comparator)
function reverse(list) function reverse(table)
local len = #list local l = #table + 1
for i = 1, math.floor(#list/2) do for index = 1, math.floor(#table / 2) do
list[len-i+1], list[i] = list[i], list[len-i+1] table[l - index], table[index] = table[index], table[l - index]
end end
return list return table
end end
function repetition(value, count) function repetition(value, count)
local table = {} local table = {}
for i = 1, count do for index = 1, count do
table[i] = value table[index] = value
end end
return table return table
end end