From 29e11e79144ab8c94f7c3d6f337013354d211c74 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sat, 7 Dec 2019 09:30:32 -0500 Subject: [PATCH] Lua functional library: make reduce accept an operator name in place of a function, add zip --- data/lua/functional.lua | 45 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/data/lua/functional.lua b/data/lua/functional.lua index f27bf5414c1..d77018623a7 100644 --- a/data/lua/functional.lua +++ b/data/lua/functional.lua @@ -47,7 +47,7 @@ function functional.choose(input, value) -- Returns element of a table with the largest @value (a function) -- Also returns the max value and the index - local max_value, best_input, best_key = -9e99 + local max_value, best_input, best_key = -math.huge for k,v in ipairs(input) do local v2 = value(v) if v2 > max_value then @@ -63,7 +63,7 @@ function functional.choose_map(input, value) -- Returns element of a table with the largest @value (a function) -- Also returns the max value and the index - local max_value, best_input, best_key = -9e99 + local max_value, best_input, best_key = -math.huge for k,v in pairs(input) do local v2 = value(k, v) if v2 > max_value then @@ -86,7 +86,34 @@ function functional.map(input, formula) return mapped_table end +local known_operators = { + ['+'] = function(a, b) return a + b end, + ['-'] = function(a, b) return a - b end, + ['*'] = function(a, b) return a * b end, + ['/'] = function(a, b) return a / b end, + ['%'] = function(a, b) return a % b end, + ['^'] = function(a, b) return a ^ b end, + ['//'] = function(a, b) return a // b end, + ['&'] = function(a, b) return a & b end, + ['|'] = function(a, b) return a | b end, + ['~'] = function(a, b) return a ~ b end, + ['<<'] = function(a, b) return a << b end, + ['>>'] = function(a, b) return a >> b end, + ['..'] = function(a, b) return a .. b end, + ['=='] = function(a, b) return a == b end, + ['~='] = function(a, b) return a ~= b end, + ['<'] = function(a, b) return a < b end, + ['>'] = function(a, b) return a > b end, + ['<='] = function(a, b) return a <= b end, + ['>='] = function(a, b) return a >= b end, + ['and'] = function(a, b) return a and b end, + ['or'] = function(a, b) return a or b end, +} + function functional.reduce(input, operator, identity) + if type(operator) == 'string' then + operator = known_operators[operator] + end local result = identity or 0 for _, v in ipairs(input) do result = operator(result, v) @@ -105,4 +132,18 @@ function functional.take_while(input, condition) return truncated_table end +-- Technically not a higher-order function, but whatever... +function functional.zip(input) + local output = {} + local _, n = functional.choose(input, function(list) return #list end) + for i = 1, n do + local elem = {} + for j, list in ipairs(input) do + elem[j] = list[i] + end + table.insert(output, elem) + end + return output +end + return functional