Advertisement
trapcodien

global_utils.lua

Dec 14th, 2019
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.47 KB | None | 0 0
  1. ---------------------------------------------------------------------------
  2. ------------  Global Functional Utils v0.4
  3. ------------  Author: Trapcodien
  4. ---------------------------------------------------------------------------
  5.  
  6. local serialization = require('serialization')
  7.  
  8. _G.import = function(path)
  9.   package.loaded[path] = nil
  10.   return require(path)
  11. end
  12.  
  13. local function simpleCompose(f, g)
  14.   return function(...)
  15.     return f(g(...))
  16.   end
  17. end
  18.  
  19. _G.fst = function(a, b) return a end
  20. _G.snd = function(a, b) return b end
  21.  
  22. _G.pipe = function(f, g, ...)
  23.   if g == nil then return f end
  24.  
  25.   local nextFn = simpleCompose(g, f)
  26.   return pipe(nextFn, ...)
  27. end
  28.  
  29. _G.compose = function(...)
  30.   local reversedArgs = reverse(pack(...))
  31.   return pipe(unpack(reversedArgs))
  32. end
  33.  
  34. _G.flip = function(f)
  35.   return curryN(2, function(a, b)
  36.     return f(b, a)
  37.   end)
  38. end
  39.  
  40. _G.apply = function(...)
  41.   local fns = pack(...)
  42.   return function(...)
  43.     return pipe(unpack(fns))(...)
  44.   end
  45. end
  46.  
  47. _G.applyTo = function(...)
  48.   local args = pack(...)
  49.   return function(...)
  50.      return pipe(...)(unpack(args))
  51.   end
  52. end
  53.  
  54. _G.pack = table.pack
  55. _G.unpack = table.unpack
  56.  
  57. _G.upper = string.upper
  58. _G.lower = string.lower
  59. _G.toUpper = string.upper
  60. _G.toLower = string.lower
  61.  
  62. _G.null = setmetatable({}, { __tostring=function() return "null" end })
  63.  
  64. -- used to stop forEach execution
  65. _G.stop = setmetatable({}, { __tostring=function() return "stop" end })
  66.  
  67. _G.length = function(t)
  68.   if isString(t) then return #t end
  69.  
  70.   local largerIndex = 0
  71.  
  72.   for k,v in pairs(t) do
  73.     if type(k) == 'number' and k > largerIndex then
  74.       largerIndex = k
  75.     end
  76.   end
  77.  
  78.   return largerIndex
  79. end
  80.  
  81. _G.countItems = function(t)
  82.   if isString(t) then return #t end
  83.  
  84.   local i = 0
  85.  
  86.   forEach(function()
  87.     i = i + 1
  88.   end, t)
  89.  
  90.   return i
  91. end
  92.  
  93. local function concatTable(t1, t2)
  94.   local t = {}
  95.   for k,v in pairs(t1) do
  96.     t[k] = v
  97.   end
  98.  
  99.   local t1length = #t1
  100.   for k2,v2 in pairs(t2) do
  101.     local newKey = type(k2) == "number" and t1length + k2 or k2
  102.     t[newKey] = v2
  103.   end
  104.  
  105.   t.n = t1length + #t2
  106.  
  107.   return t
  108. end
  109.  
  110. _G.curry = function(func, num_args)
  111.   num_args = num_args or debug.getinfo(func, "u").nparams
  112.   if num_args < 2 then return func end
  113.   local function helper(argtrace, n)
  114.     if n < 1 then
  115.       return func(table.unpack(argtrace))
  116.     else
  117.       return function (...)
  118.         return helper(concatTable(argtrace, pack(...)), n - select("#", ...))
  119.       end
  120.     end
  121.   end
  122.   return helper({}, num_args)
  123. end
  124.  
  125. _G.curryN = function(num_args, func) return curry(func, num_args) end
  126.  
  127. _G.flatten = function(t)
  128.   local ret = {}
  129.   for _, v in ipairs(t) do
  130.     if type(v) == 'table' then
  131.       for _, fv in ipairs(flatten(v)) do
  132.         ret[#ret + 1] = fv
  133.       end
  134.     else
  135.       ret[#ret + 1] = v
  136.     end
  137.   end
  138.   return ret
  139. end
  140.  
  141. _G.concat = curryN(2, function(t1, t2)
  142.   if isString(t1) then return t1 .. t2 end
  143.   return concatTable(t1, t2)
  144. end)
  145.  
  146. local stringCount = function(substr, str)
  147.   local i = 0
  148.   local foundPos = 0
  149.  
  150.   while isNotNil(foundPos) do
  151.     foundPos = string.find(str, substr, foundPos + 1)
  152.     if isNotNil(foundPos) then
  153.       i = i +1
  154.     end
  155.   end
  156.  
  157.   return i
  158. end
  159.  
  160. _G.countWhen = curryN(2, function(predicate, t)
  161.   local i = 0
  162.  
  163.   forEach(function(v, k)
  164.     if predicate(v, k) then
  165.       i = i + 1
  166.     end
  167.   end, t)
  168.  
  169.   return i
  170. end)
  171.  
  172. _G.count = curryN(2, function(v, t)
  173.   if isString(v) and isString(t) then return stringCount(v, t) end
  174.   return countWhen(identical(v), t)
  175. end)
  176.  
  177. local simpleMerge = function(t1, t2)
  178.   local ret = clone(t1)
  179.  
  180.   forEach(function(v, k)
  181.     ret[k] = v
  182.   end, t2)
  183.  
  184.   return ret
  185. end
  186.  
  187. _G.assign = function(t1, t2, ...)
  188.   if isNil(t2) then return t1 end
  189.   local merged = simpleMerge(t1, t2)
  190.   return assign(merged, ...)
  191. end
  192.  
  193. _G.mergeTo = curryN(2, simpleMerge)
  194. _G.merge = mergeTo
  195.  
  196. _G.withDefault = flip(merge)
  197.  
  198. _G.complement = function(predicate)
  199.   return function(...)
  200.     return not predicate(...)
  201.   end
  202. end
  203.  
  204. _G.ternary = curryN(3, function(bool, v1, v2)
  205.   if bool then
  206.     return v1
  207.   else
  208.     return v2
  209.   end
  210. end)
  211.  
  212. _G.Nil = function() return nil end
  213. _G.toNil = Nil
  214.  
  215. _G.Table = pack
  216. _G.toTable = Table
  217.  
  218. _G.String = tostring
  219. _G.toString = String
  220.  
  221. _G.Number = function(x)
  222.   if isBoolean(x) then
  223.     return ternary(x, 1, 0)
  224.   elseif isNil(x) then
  225.     return 0
  226.   end
  227.  
  228.   return tonumber(x)
  229. end
  230.  
  231. _G.toNumber = Number
  232.  
  233. _G.isStringIsNumber = function(v)
  234.   if not isString(v) then return false end
  235.   return isNumber(Number(v))
  236. end
  237.  
  238. _G.max = curryN(2, function(a, b)
  239.   return math.max(a, b)
  240. end)
  241.  
  242. _G.min = curryN(2, function(a, b)
  243.   return math.min(a, b)
  244. end)
  245.  
  246. _G.abs = math.max
  247.  
  248. _G.negate = function(x) return -x end
  249.  
  250. _G.of = function(v) return {v} end
  251.  
  252. _G.isWhitespace = function(v)
  253.   return v == ' ' or v == '\t' or v == '\n'
  254. end
  255.  
  256. _G.isNotWhitespace = complement(isWhitespace)
  257.  
  258. -- ACCESSORS/UPDATERS
  259.  
  260. _G.replaceCharAt = curryN(3, function(pos, c, str)
  261.   if pos < 0 then
  262.     pos = #str + 1 + abs(pos)
  263.   end
  264.   return string.sub(str, 1, pos - 1) .. c .. string.sub(str, pos + 1)
  265. end)
  266.  
  267. _G.removeCharAt = curryN(2, function(pos, str)
  268.   return replaceCharAt(pos, '', str)
  269. end)
  270.  
  271. _G.insertCharAt = curryN(3, function(pos, c, str)
  272.   if pos < 0 then
  273.     pos = #str + 2 + abs(pos)
  274.   elseif pos == 0 then
  275.     pos = 1
  276.   end
  277.  
  278.   return string.sub(str, 0, pos - 1) .. c .. string.sub(str, pos)
  279. end)
  280.  
  281. _G.prop = curryN(2, function(k, t)
  282.   if isString(t) then return string.sub(t, k, k) end
  283.   if isNotTable(t) then return nil end
  284.   return t[k]
  285. end)
  286.  
  287. _G.propOr = curryN(3, function(fallbackValue, k, t)
  288.   return prop(k, t) or fallbackValue
  289. end)
  290.  
  291. _G.setProp = curryN(3, function(k, v, t)
  292.   if isString(t) then
  293.     return replaceCharAt(k, v, t)
  294.   end
  295.  
  296.   if isNotTable(t) then return t end
  297.   local newTable = clone(t)
  298.   newTable[k] = v
  299.  
  300.   return newTable
  301. end)
  302.  
  303. _G.setNonNilProps = curryN(3, function(k, v, t)
  304.   if isString(t) and isNotNil(prop(k, t)) then
  305.     return replaceCharAt(k, v, t)
  306.   end
  307.  
  308.   if isNotTable(t) then return t end
  309.   if isNil(t[k]) then return t end
  310.   return setProp(k, v, t)
  311. end)
  312.  
  313. _G.removeProp = curryN(2, function(k, t)
  314.   return omit(k)(t)
  315. end)
  316.  
  317. _G.updateProp = curryN(3, function(k, f, t)
  318.   return setProp(k, f(prop(k, t)), t)
  319. end)
  320.  
  321. _G.updateNonNilProp = curryN(3, function(k, f, t)
  322.   local v = prop(k, t)
  323.   if isNil(v) then return t end
  324.   return setProp(k, f(v), t)
  325. end)
  326.  
  327. _G.path = function(...)
  328.   local ks = pack(...)
  329.   local firstKey = head(ks)
  330.  
  331.   return function(t)
  332.     if isNil(t) or isNil(firstKey) then return t end
  333.     return path(unpack(tail(ks))) (prop(firstKey, t))
  334.   end
  335. end
  336.  
  337. _G.pathOr = function(fallbackValue, ...)
  338.   local args = pack(...)
  339.   return function(t)
  340.     return path(unpack(args))(t) or fallbackValue
  341.   end
  342. end
  343.  
  344. -------------- TODO
  345. _G.setPath = nil
  346. _G.setNonNilPath = nil
  347. _G.removePath = nil
  348. _G.updatePath = nil
  349. _G.updateNonNilPath = nil
  350.  
  351. _G.propCompare = nil
  352. _G.pathCompare = nil
  353. _G.propEq = nil
  354. _G.pathEq = nil
  355. _G.propIdentical = nil
  356. _G.pathIdentical = nil
  357.  
  358. -------------------
  359.  
  360. _G.keys = function(t)
  361.   return map(snd, t)
  362. end
  363.  
  364. _G.omit = function(...)
  365.   local keys = pack(...)
  366.   return function(t)
  367.     return reject(function(value, key)
  368.       local foundIndex = findKey(identical(key), keys)
  369.       return isNotNil(foundIndex)
  370.     end, t)
  371.   end
  372. end
  373.  
  374. _G.pick = function(...)
  375.   local keys = pack(...)
  376.   return function(t)
  377.     return filter(function(value, key)
  378.       local foundIndex = findKey(identical(key), keys)
  379.       return isNotNil(foundIndex)
  380.     end, t)
  381.   end
  382. end
  383.  
  384. _G.append = curryN(2, function(v, t)
  385.   return concat(t, {v})
  386. end)
  387.  
  388. _G.prepend = curryN(2, function(v, t)
  389.   return concat({v}, t)
  390. end)
  391.  
  392. _G.take = curryN(2, function(n, t)
  393.   if isString(t) then return string.sub(t, 0, n) end
  394.  
  395.   local ret = {}
  396.   local taken = 0
  397.  
  398.   forEach(function(v, k)
  399.     if taken >= n then return stop end
  400.     if isNumber(k) then
  401.       ret[k] = v
  402.       taken = taken + 1
  403.     end
  404.   end, t)
  405.  
  406.   return ret
  407. end)
  408.  
  409. _G.drop = curryN(2, function(n, t)
  410.   if n <= 0 then return t end
  411.   if isString(t) then
  412.     return string.sub(t, n + 1)
  413.   end
  414.  
  415.   local ret = {}
  416.   local dropped = 0
  417.   local i = 1
  418.  
  419.   forEach(function(v, k)
  420.     if dropped >= n then
  421.       ret[i] = v
  422.       i = i + 1
  423.     else
  424.       dropped = dropped + 1
  425.     end
  426.   end, t)
  427.  
  428.   return ret
  429. end)
  430.  
  431. _G.takeLast = curryN(2, function(n, t)
  432.   if isString(t) then
  433.     return string.sub(t, -n)
  434.   end
  435.  
  436.   local size = length(compact(t))
  437.   local toDrop = math.max(0, size - n)
  438.   return drop(toDrop, t)
  439. end)
  440.  
  441. _G.dropLast = curryN(2, function(n, t)
  442.   local size = length(compact(t))
  443.   local toTake = math.max(0, size - n)
  444.   return take(toTake, t)
  445. end)
  446.  
  447. local stringDropUntil = function(predicate, str)
  448.   local ret = ''
  449.   local shouldDrop = true
  450.  
  451.   forEach(function(c, k)
  452.     if shouldDrop then
  453.       shouldDrop = not predicate(c, k)
  454.     end
  455.  
  456.     if not shouldDrop then
  457.       ret = ret .. c
  458.     end
  459.   end, str)
  460.  
  461.   return ret
  462. end
  463.  
  464. _G.dropUntil = curryN(2, function(predicate, t)
  465.   if isString(t) then return stringDropUntil(predicate, t) end
  466.  
  467.   local ret = {}
  468.   local shouldDrop = true
  469.   local i = 1
  470.  
  471.   forEachIndex(function(v, k)
  472.     if shouldDrop then
  473.       shouldDrop = not predicate(v, k)
  474.     end
  475.  
  476.     if not shouldDrop then
  477.       ret[i] = v
  478.       i = i + 1
  479.     end
  480.   end, t)
  481.  
  482.   return ret  
  483. end)
  484.  
  485. local stringTakeUntil = function(predicate, str)
  486.   local ret = ''
  487.   local shouldTake = true
  488.  
  489.   forEach(function(c, k)
  490.     shouldTake = not predicate(c, k)
  491.     if not shouldTake then return stop end
  492.     ret = ret .. c
  493.   end, str)  
  494.  
  495.   return ret
  496. end
  497.  
  498. _G.takeUntil = curryN(2, function(predicate, t)
  499.   if isString(t) then return stringTakeUntil(predicate, t) end
  500.  
  501.   local ret = {}
  502.   local i = 1
  503.   local shouldTake = true
  504.  
  505.   forEachIndex(function(v, k)
  506.     shouldTake = not predicate(v, k)
  507.     if not shouldTake then return stop end
  508.     ret[i] = v
  509.     i = i + 1
  510.   end, t)
  511.  
  512.   return ret
  513. end)
  514.  
  515. _G.dropLastUntil = curryN(2, function(predicate, t)
  516.   return applyTo(t)(
  517.     reverse,
  518.     dropUntil(predicate),
  519.     reverse
  520.   )
  521. end)
  522.  
  523. _G.takeLastUntil = curryN(2, function(predicate, t)
  524.   return applyTo(t)(
  525.     reverse,
  526.     takeUntil(predicate),
  527.     reverse
  528.   )
  529. end)
  530.  
  531. _G.head = function(t)
  532.   if isString(t) then return prop(1, t) end
  533.  
  534.   local foundHead = nil
  535.  
  536.   forEach(function(v)
  537.     foundHead = v
  538.     return stop
  539.   end, t)
  540.  
  541.   return foundHead
  542. end
  543.  
  544. _G.first = head
  545.  
  546. _G.tail = drop(1)
  547.  
  548. _G.last = function(t)
  549.   if isString(t) then return string.sub(t, -1) end
  550.   return t[length(t)]
  551. end
  552.  
  553. -------- STRING UTILS ----------
  554. _G.trimStart = dropUntil(isNotWhitespace)
  555. _G.trimEnd = dropLastUntil(isNotWhitespace)
  556. _G.trim = pipe(trimStart, trimEnd)
  557.  
  558. _G.join = curryN(2, function(sep, t)
  559.   return table.concat(t, sep)
  560. end)
  561.  
  562. local simpleSplit = function(sep, str)
  563.   if str == "" then return nil end
  564.  
  565.   local sepPos, nextPos = string.find(str, sep)
  566.   if isNil(nextPos) then return str end
  567.  
  568.   local firstWord = string.sub(str, 1, sepPos - 1)
  569.   local secondWord = string.sub(str, nextPos + 1)
  570.  
  571.   return firstWord, secondWord
  572. end
  573.  
  574. _G.split = curryN(2, function(sep, str)
  575.   local ret = {}
  576.   local restString = str
  577.  
  578.   while isNotEmpty(restString) do
  579.     local firstWord, secondWord = simpleSplit(sep, restString)
  580.     if isNotNil(firstWord) then
  581.       table.insert(ret, firstWord)
  582.     end
  583.     restString = secondWord
  584.   end
  585.  
  586.   return ret
  587. end)
  588.  
  589. _G.startsWith = curryN(2, function(substr, str)
  590.   return take(#substr, str) == substr
  591. end)
  592.  
  593. _G.endWith = curryN(2, function(substr, str)
  594.   return takeLast(#substr, str) == substr
  595. end)
  596.  
  597. _G.contains = curryN(2, function(value, t)
  598.   if isString(value) and isString(t) then
  599.     return Boolean(string.find(t, value))
  600.   end
  601.  
  602.   local valueFound = false
  603.  
  604.   forEach(function(v)
  605.     if value == v then
  606.       valueFound = true
  607.       return stop
  608.     end
  609.   end, t)
  610.  
  611.   return valueFound
  612. end)
  613.  
  614. _G.oneOf = flip(contains)
  615.  
  616. -- TYPE PREDICATES
  617.  
  618. _G.is = curryN(2, function(givenType, value)
  619.   return type(value) == givenType
  620. end)
  621.  
  622. _G.isNot = curryN(2, function(givenType, value)
  623.   return not (type(value) == givenType)
  624. end)
  625.  
  626. _G.isString = is('string')
  627. _G.isTable = is('table')
  628. _G.isNumber = is('number')
  629. _G.isBoolean = is('boolean')
  630.  
  631. _G.isNotString = isNot('string')
  632. _G.isNotTable = isNot('table')
  633. _G.isNotNumber = isNot('number')
  634. _G.isNotBoolean = isNot('boolean')
  635.  
  636. _G.isNull = function(v) return v == null end
  637. _G.isNotNull = complement(isNull)
  638.  
  639. _G.isNil = function(v) return v == nil or v == null end
  640. _G.isNotNil = complement(isNil)
  641.  
  642. _G.Boolean = function(v)
  643.   local isFalsy = isNil(v) or v == '' or v == 0 or v == false
  644.   return not isFalsy
  645. end
  646.  
  647. _G.isTruthy = Boolean
  648. _G.isFalsy = complement(Boolean)
  649.  
  650. _G.isEmpty = function(v)
  651.   if v == '' then return true end
  652.   if isNil(v) then return true end
  653.  
  654.   if isTable(v) then
  655.     local iterated = false
  656.  
  657.     forEach(function(x)
  658.       iterated = true
  659.       return stop
  660.     end, v)
  661.  
  662.     return not iterated
  663.   end
  664.  
  665.   return false
  666. end
  667.  
  668. _G.isNotEmpty = complement(isEmpty)
  669.  
  670. _G.isHuge = function(x) return x == math.huge end
  671. _G.isNotHuge = complement(isHuge)
  672.  
  673. _G.byte = function(c)
  674.   return string.byte(c)
  675. end
  676.  
  677. _G.char = function(code)
  678.   return string.char(code)
  679. end
  680.  
  681. _G.isStringIsNumeric = function(v)
  682.   if not isString(v) then return false end
  683.   return isStringIsNumber(head(v))
  684. end
  685.  
  686. _G.lt = curryN(2, function(a, b)
  687.   return b < a
  688. end)
  689.  
  690. _G.lte = curryN(2, function(a, b)
  691.   return b <= a
  692. end)
  693.  
  694. _G.gt = curryN(2, function(a, b)
  695.   return b > a
  696. end)
  697.  
  698. _G.gte = curryN(2, function(a, b)
  699.   return b >= a
  700. end)
  701.  
  702. _G.isZero = function(x) return x == 0 end
  703. _G.isNotZero = complement(isZero)
  704.  
  705. -- BASIC LOGIC
  706.  
  707. _G.identical = curryN(2, function(a, b) return a == b end)
  708. _G.notIdentical = curryN(2, function(a, b) return not(a == b) end)
  709.  
  710. _G.isTrue = identical(true)
  711. _G.isNotTrue = complement(isTrue)
  712.  
  713. _G.isFalse = identical(false)
  714. _G.isNotFalse = complement(isFalse)
  715.  
  716. _G.xor = curryN(2, function(a, b)
  717.   return (a == true and b == false) or (a == false and b == true)
  718. end)
  719.  
  720. _G.ifElse = curryN(3, function(predicate, transformerThen, transformerElse)
  721.   return function(...)
  722.     if predicate(...) then
  723.       return transformerThen(...)
  724.     else
  725.      return transformerElse(...)
  726.     end
  727.   end
  728. end)
  729.  
  730. _G.when = curryN(2, function(predicate, transformerThen)
  731.   return function(...)
  732.     return ifElse(predicate, transformerThen, identity)(...)
  733.   end
  734. end)
  735.  
  736. _G.defaultTo = curryN(2, function(fallbackValue, v)
  737.   if isNotNil(v) then return v end
  738.   return fallbackValue
  739. end)
  740.  
  741. _G.equalsBy = curryN(2, function(comparator, a, b)
  742.   if (a == b) then return true end
  743.  
  744.   if isNotTable(a) or isNotTable(b) then return false end
  745.  
  746.   local isShallowEquals = true
  747.   local iterated = false
  748.  
  749.   forEach(function(value, key)
  750.     iterated = true
  751.     if not comparator(value, b[key]) then
  752.       isShallowEquals = false
  753.       return stop
  754.     end
  755.   end, a)
  756.  
  757.   forEach(function(value, key)
  758.     iterated = true
  759.     if not comparator(value, a[key]) then
  760.       isShallowEquals = false
  761.       return stop
  762.     end
  763.   end, b)
  764.  
  765.   if not iterated then return true end
  766.   return isShallowEquals  
  767. end)
  768.  
  769. _G.notEqualsBy = curryN(2, function(comparator, a, b)
  770.     return not equalsBy(comparator, a, b)    
  771. end)
  772.  
  773. _G.equals = equalsBy(identical)
  774. _G.notEquals = notEqualsBy(identical)
  775.  
  776. _G.deepEquals = curryN(2, function(a, b)
  777.   return equalsBy(deepEquals, a, b)
  778. end)
  779.  
  780. _G.notDeepEquals = curryN(2, function(a, b)
  781.   return not equalsBy(notDeepEquals, a, b)
  782. end)
  783.  
  784. _G.both = curryN(3, function(predicate1, predicate2, value)
  785.   return predicate1(value) and predicate2(value)
  786. end)
  787.  
  788. _G.either = curryN(3, function(predicate1, predicate2, value)
  789.   return predicate1(value) or predicate2(value)
  790. end)
  791.  
  792. _G.allPass = curryN(2, function(predicates, value)
  793.   local reducer = function(acc, p) return acc and p(value) end
  794.   return reduce(reducer, true, predicates)
  795. end)
  796.  
  797. _G.anyPass = curryN(2, function(predicates, value)
  798.   local reducer = function(acc, p) return acc or p(value) end
  799.   return reduce(reducer, false, predicates)
  800. end)
  801.  
  802. _G.identity = function(x) return x end
  803. _G.noop = function() end
  804. _G.always = function(...)
  805.   local args = pack(...)
  806.   return function()
  807.     return unpack(args)
  808.   end
  809. end
  810.  
  811. _G.tap = function(f)
  812.   return function(...)
  813.     f(...)
  814.     return ...
  815.   end
  816. end
  817.  
  818. _G.log = tap(print)
  819.  
  820. _G.add = curryN(2, function(a, b) return a + b end)
  821. _G.sub = curryN(2, function(a, b) return b - a end)
  822. _G.inc = add(1)
  823. _G.dec = add(-1)
  824.  
  825. local a = byte('a')
  826. local A = byte('A')
  827. local z = byte('z')
  828. local Z = byte('Z')
  829.  
  830. _G.isAlphaMin = function(v)
  831.   if not isString(v) then return false end
  832.   local code = byte(v)
  833.   return code >= a and code <= z    
  834. end
  835.  
  836. _G.isAlphaMaj = function(v)
  837.   if not isString(v) then return false end
  838.   local code = byte(v)
  839.   return code >= A and code <= Z
  840. end
  841.  
  842. _G.isAlpha = either(isAlphaMin, isAlphaMaj)
  843. _G.isAlphaNum = either(isStringIsNumeric, isAlpha)
  844.  
  845. -- TABLE FUNCTIONS
  846.  
  847. _G.compact = function(t)
  848.   if isString(t) then return t end
  849.  
  850.   local ret = {}
  851.   local i = 0
  852.  
  853.   forEach(function(v, k)
  854.     if isNil(v) then return nil end
  855.     if isNumber(k) then
  856.       i = i + 1
  857.       ret[i] = v
  858.     else
  859.       ret[k] = v
  860.     end
  861.   end, t)
  862.  
  863.   if t.n then ret.n = i end
  864.  
  865.   return ret
  866. end
  867.  
  868. _G.reverse = function(t)
  869.   if isString(t) then return string.reverse(t) end
  870.  
  871.   local ret = {}
  872.   ret.n = t.n
  873.  
  874.   objForEach(function(v, k)
  875.     ret[k] = v
  876.   end, t)  
  877.  
  878.   local tlen = length(t)
  879.   local i = 1
  880.  
  881.   while i <= tlen do
  882.     ret[tlen - (i - 1)] = t[i]    
  883.     i = i + 1
  884.   end
  885.  
  886.   return ret
  887. end
  888.  
  889. _G.forEach = curryN(2, function(f, t)
  890.   if isString(t) then
  891.     for i=1, #t do
  892.       local c = string.sub(t, i, i)
  893.       if f(c, i) == stop then return nil end
  894.     end
  895.     return nil
  896.   end
  897.  
  898.   for k, v in pairs(t) do
  899.     if notIdentical(k, 'n') then
  900.       if f(v, k) == stop then return nil end
  901.     end
  902.   end
  903. end)
  904.  
  905. _G.forEachIndex = curryN(2, function(f, t)
  906.   if isString(t) then
  907.     return forEach(f, t)
  908.   end
  909.  
  910.   for k, v in pairs(t) do
  911.     if (isNumber(k)) then
  912.       if f(v, k) == stop then return nil end
  913.     end
  914.   end
  915. end)
  916.  
  917. _G.objForEach = curryN(2, function(f, t)
  918.   for k, v in pairs(t) do
  919.     if isNotNumber(k) then
  920.       if f(v, k) == stop then return nil end
  921.     end
  922.   end
  923. end)
  924.  
  925. _G.forEachRight = curryN(2, function(f, t)
  926.   if isString(t) then
  927.     for i=#t,1,-1 do
  928.       local c = string.sub(t, i, i)
  929.       if f(c, i) == stop then return nil end
  930.     end
  931.     return nil
  932.   end
  933.  
  934.   t = compact(t)
  935.   local tlen = length(t)
  936.  
  937.   for i=tlen,1,-1 do
  938.     if f(t[i], i) == stop then return nil end
  939.   end
  940. end)
  941.  
  942. _G.forEachLast = forEachRight
  943.  
  944. _G.forEachIndexRight = curryN(2, function(f, t)
  945.   return forEachRight(function(v, k)
  946.     return f(k)
  947.   end, t)
  948. end)
  949.  
  950. _G.forEachIndexLast = forEachIndexRight
  951.  
  952. local mapString = function(f, str)
  953.   local ret = ''
  954.  
  955.   forEach(function(v)
  956.     ret = ret .. f(v)
  957.   end, str)
  958.  
  959.   return ret
  960. end
  961.  
  962. _G.map = curryN(2, function(f, t)
  963.   if isString(t) then return mapString(f, t) end
  964.  
  965.   local ret = {}
  966.   ret.n = t.n
  967.  
  968.   forEach(function(v, k)
  969.     ret[k] = f(v, k)
  970.   end, t)
  971.  
  972.   return ret
  973. end)
  974.  
  975. _G.deepMap = curryN(2, function(f, t)
  976.   if isTable(t) then return map(deepMap(f), t) end
  977.   return f(t)
  978. end)
  979.  
  980. local filterString = function(predicate, str)
  981.   local ret = ''
  982.  
  983.   forEach(function(value, key)
  984.     if predicate(value, key) then
  985.       ret = ret .. value
  986.     end
  987.   end, str)
  988.  
  989.   return ret
  990. end
  991.  
  992. _G.filter = curryN(2, function(predicate, t)
  993.   if isString(t) then return filterString(predicate, t) end  
  994.  
  995.   local ret = {}
  996.   forEach(function(value, key)
  997.     if predicate(value, key) then
  998.       ret[key] = value
  999.     end
  1000.   end, t)
  1001.  
  1002.   if type(t.n) == 'number' then
  1003.     ret.n = length(ret)
  1004.   end
  1005.  
  1006.   return compact(ret)
  1007. end)
  1008.  
  1009. _G.reject = curryN(2, function(predicate, t)
  1010.   return filter(complement(predicate), t)
  1011. end)
  1012.  
  1013. _G.reduce = curryN(3, function(reducer, initialAcc, t)
  1014.   local acc = initialAcc
  1015.   forEach(function(value)
  1016.     acc = reducer(acc, value)
  1017.   end, t)
  1018.   return acc
  1019. end)
  1020.  
  1021. _G.find = curryN(2, function(predicate, t)
  1022.   local foundValue = nil
  1023.  
  1024.   forEach(function(v, k)
  1025.     if predicate(v, k) then
  1026.       foundValue = v;
  1027.       return stop
  1028.     end
  1029.   end, t)
  1030.  
  1031.   return foundValue
  1032. end)
  1033.  
  1034. _G.findKey = curryN(2, function(predicate, t)
  1035.   local foundKey = nil
  1036.  
  1037.   forEach(function(v, k)
  1038.     if predicate(v, k) then
  1039.       foundKey = k
  1040.       return stop
  1041.     end    
  1042.   end, t)
  1043.  
  1044.   return foundKey
  1045. end)
  1046.  
  1047. _G.findByKey = curryN(2, function(predicate, t)
  1048.   return find(function(v, k)
  1049.     return predicate(k)
  1050.   end, t)
  1051. end)
  1052.  
  1053. _G.clone = map(identity)
  1054. _G.deepClone = deepMap(identity)
  1055.  
  1056. local function dumpTable(tbl, indent)
  1057.   if not (type(tbl) == 'table') then
  1058.     print(tbl)
  1059.     return nil
  1060.   end
  1061.   if not indent then indent = 0 end
  1062.   for k, v in pairs(tbl) do
  1063.     formatting = string.rep("  ", indent) .. k .. ": "
  1064.     if type(v) == "table" then
  1065.       print(formatting)
  1066.       dumpTable(v, indent+1)
  1067.     elseif type(v) == 'boolean' then
  1068.       print(formatting .. tostring(v))      
  1069.     else
  1070.       print(formatting .. v)
  1071.     end
  1072.   end
  1073. end
  1074.  
  1075. _G.dump = function(...)
  1076.   local args = pack(...)
  1077.  
  1078.   forEach(function(arg)
  1079.     dumpTable(arg)
  1080.   end, args)
  1081.  
  1082.   return ...
  1083. end
  1084.  
  1085. _G.serialize = serialization.serialize
  1086. _G.unserialize = serialization.unserialize
  1087. _G.parse = unserialize
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement