SHARE
TWEET

global_utils.lua

trapcodien Dec 14th, 2019 (edited) 91 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top