Skip to content

Instantly share code, notes, and snippets.

@kigiri
Created December 11, 2018 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kigiri/0c4e43893faa54ad5987e788a28a7dcd to your computer and use it in GitHub Desktop.
Save kigiri/0c4e43893faa54ad5987e788a28a7dcd to your computer and use it in GitHub Desktop.
local function empty(tbl)
if type(tbl) == 'string' then return #tbl == 0 end
if type(tbl) ~= 'table' then return true end
if #tbl ~= 0 then return false end
for k, v in pairs(tbl) do return false end
return true
end
local function len(tbl)
if type(tbl) ~= 'table' then return 0 end
local count = 0
for k, v in pairs(tbl) do count = count + 1 end
return count
end
local function concat1(a, b)
for _, v in ipairs(b) do table.insert(a, v) end
return a
end
local function concat(...)
t = {}
for _, v in ipairs({...}) do concat1(t, v) end
return t
end
local function assign1(a, b)
for k, v in pairs(b) do a[k] = v end
return a
end
local function assign(t, ...)
for _, v in ipairs({...}) do assign1(t, v) end
return t
end
local function spread(...) return assign({}, ...) end
local function curryFlip(action)
return function (func) return function (...) return action(..., func) end end
end
function eval(strFunc)
local func, err = loadstring('return function (x) return '..strFunc..' end')
if err then print(err) end
return func()
end
local function map(tbl, func)
if type(func) == 'string' then func = eval(func) end
local t = {}
for k, v in pairs(tbl) do t[k] = func(v, k) end
return t
end
local function get(tbl, key) return tbl[key] end
local function filter(tbl, func)
if type(func) == 'string' then func = eval(func) end
local t = {}
for k, v in pairs(tbl) do if func(v) then t[k] = v end end
return t
end
local function fold(tbl, acc, func)
if type(func) == 'string' then func = eval(func) end
for k, v in pairs(tbl) do acc = func(acc, v, k) end
return acc
end
local function reduce(tbl, func)
if type(func) == 'string' then func = eval(func) end
if (empty(tbl)) then error('reduce was called with an empty table') end
local head = table.remove(tbl, 1)
return fold(tbl, head, func)
end
local function join(tbl, sep)
if type(tbl) ~= 'table' then return '' end
return table.concat(tbl, sep or '')
end
local function nTbl(n)
local t = {}
for i = 1, n do t[i] = i end
return t
end
local function keys(tbl)
local t = {}
for k, _ in pairs(list) do table.insert(t, k) end
return t
end
local function uniq(tbl)
local t = {}
for _, l in ipairs(list) do
t[l] = true
end
return keys(t)
end
local function flat(tbl)
local t = {}
for _, v in ipairs(tbl) do
if not type(v) == 'table' then
table.insert(t, v)
else
for _, vv in ipairs(v) do
table.insert(t, vv)
end
end
end
return t
end
local T = {}
setmetatable(T, {
__call = function (self, ...)
local args = {...}
if #args == 0 then return setmetatable({}, T) end
if #args == 1 then
local arg = args[1]
if not arg then return setmetatable({}, T) end
if type(arg) == 'table' then return setmetatable(arg, T) end
return setmetatable({arg}, T)
end
return setmetatable(args, T)
end
})
-- T.__len =
-- T.__tostring =
T.__concat = function (self, tbl)
--print('lhs', self)
--print('rhs', tbl)
return setmetatable(assign1(assign1({}, self), tbl), T)
end
local function register(proto, name, func)
if not proto.__index then proto.__index = { new = proto } end
proto.__index[name] = func
end
local function registerChained(proto, name, func)
return register(proto, name, function (...)
return setmetatable(func(...), proto)
end)
end
local g = T({ abc = 'abc' })..T({ def = 'def' })
for k, v in pairs(g) do print(k, v) end
--local g2 = g:map(function (n) return n..tostring(12) end)
--for k, v in pairs(g2) do print(k, v) end
function slice(tbl, first, last, step)
local size = #tbl
if first < 0 then first = size + first end
if last < 0 then last = size + last end
local t = {}
for i = first or 1, last or size, step or 1 do
table.insert(t, tbl[i])
end
return t
end
local mapper = curryFlip(map)
local filterer = curryFlip(filter)
local folder = curryFlip(fold)
local reducer = curryFlip(fold)
local joiner = curryFlip(join)
local getter = curryFlip(get)
registerChained(T, 'map', map)
registerChained(T, 'fold', fold)
registerChained(T, 'slice', slice)
registerChained(T, 'filter', filter)
registerChained(T, 'reduce', reduce)
register(T, 'join', join)
register(T, 'set', function (self, key, value)
return self..{ [key] = value }
end)
for i,v in ipairs(nTbl(20)) do
print(i,v)
end
print(T(nTbl(20))
:slice(2, -2)
:filter('x % 2 == 0')
:map('x + 10')
:join('-'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment