@@ -4,8 +4,32 @@ for i = #list, 2, -1 do local j = math.random(i) list[i], list[j] = list[j], list[i] end + return list +end + +fn.cshuf = function(list) + return fn.shuffle(table.copy(list)) +end + +fn.urnd = function(min,max) + local r = {} + for i=min,max do r[1 + (i - min)] = i end + fn.shuffle(r) + return r +end + +fn.uniq = function(lst) + local hash = {} + local new = {} + for i,v in ipairs(lst) do + if not hash[v] then + hash[v] = true + new[#new+1] = v + end + end + return new end fn.scramble = function(list) local new = table.copy(list) @@ -39,15 +63,17 @@ end return new end -fn.deepmerge = function(base,override) +fn.deepmerge = function(base,override,func) local new = {} local keys = fn.merge(fn.keys(base),fn.keys(override)) for _,k in pairs(keys) do if type(base[k]) == 'table' and type(override[k]) == 'table' then - new[k] = fn.deepmerge(base[k], override[k]) + new[k] = fn.deepmerge(base[k], override[k], func) + elseif func and override[k] and base[k] then + new[k] = func(base[k],override[k], k) elseif override[k] then new[k] = override[k] else new[k] = base[k] @@ -84,30 +110,35 @@ end fn.pick = function(lst) local keys = fn.keys(lst) - return keys[math.random(#keys)] + local k = keys[math.random(#keys)] + return k, lst[k] end fn.unpack = function(tbl,i) - if i and #tbl == i then return tbl[i] end i = i or 1 + if #tbl == i then return tbl[i] end return tbl[i], fn.unpack(tbl, i+1) end -fn.each = function(tbl,fn) +fn.split = function(...) return fn.unpack(sorcery.lib.str.explode(...)) end + +fn.each = function(tbl,f) local r = {} for k,v in pairs(tbl) do - r[#r+1] = fn(v,k) + local v, c = f(v,k) + r[#r+1] = v + if c == false then break end end return r end -fn.each_o = function(tbl,fn) +fn.each_o = function(tbl,f) local keys = fn.keys(tbl) table.sort(keys) return fn.each(keys, function(k,i) - return fn(tbl[k],k,i) + return f(tbl[k],k,i) end) end fn.iter = function(tbl,fn) @@ -140,14 +171,38 @@ fn.walk = function(tbl,path) if type(path) == 'table' then for _,p in pairs(path) do - if tbl[p] == nil then return nil end + if tbl == nil or tbl[p] == nil then return nil end tbl = tbl[p] end else tbl = tbl[path] end return tbl end + +fn.proto = function(tbl,proto) + local meta = getmetatable(tbl) + local nm = {__index = proto or tbl} + if meta ~= nil then + nm = table.copy(meta) + nm[__index] = proto + nm[__metatable] = meta + end + return setmetatable(tbl or {},nm) +end + +fn.case = function(e, c) + if type(c[e]) == 'function' + then return (c[e])(e) + else return c[e] + end +end + +fn.cond = function(exp, c) + for i, v in ipairs(c) do + if c[1](exp) then return c[2](exp) end + end +end return fn