From bd150ce209b8ece8170fc0da557a01de1e3c04f5 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Wed, 7 Sep 2022 11:38:14 +0200 Subject: [PATCH] Move iterator utils from func to own module --- func.lua | 118 ++++++++------------------------------------------- init.lua | 1 + iterator.lua | 78 ++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 101 deletions(-) create mode 100644 iterator.lua diff --git a/func.lua b/func.lua index f587deb..3200206 100644 --- a/func.lua +++ b/func.lua @@ -1,6 +1,6 @@ -- Localize globals -local error, coroutine, math, modlib, unpack, select, setmetatable - = error, coroutine, math, modlib, unpack, select, setmetatable +local error, coroutine, modlib, unpack, select, setmetatable + = error, coroutine, modlib, unpack, select, setmetatable -- Set environment local _ENV = {} @@ -92,62 +92,6 @@ function aggregate(binary_func, total, ...) return total end ---+ For all functions which aggregate over single values, use modlib.table.ivalues - not ipairs - for lists! ---+ Otherwise they will be applied to the indices. -iterator = {} - -function iterator.aggregate(binary_func, total, ...) - for value in ... do - total = binary_func(total, value) - end - return total -end - -function iterator.min(less_than_func, ...) - local min - for value in ... do - if min == nil or less_than_func(value, min) then - min = value - end - end - return min -end - -function iterator.count(...) - local count = 0 - for _ in ... do - count = count + 1 - end - return count -end - -function iterator.sum(...) - return iterator.aggregate(add, ...) -end - -function iterator.average(...) - local count = 0 - local sum = 0 - for value in ... do - count = count + 1 - sum = sum + value - end - return sum / count -end - ---: ... **restartable** iterator --- While a single pass method for calculating the standard deviation exists, it is highly inaccurate -function iterator.standard_deviation(...) - local avg = iterator.average(...) - local count = 0 - local sum = 0 - for value in ... do - count = count + 1 - sum = sum + (value - avg)^2 - end - return math.sqrt(sum / count) -end - function override_chain(func, override) return function(...) func(...) @@ -162,63 +106,35 @@ end -- Functional wrappers for Lua's builtin metatable operators (arithmetic, concatenation, length, comparison, indexing, call) -function add(a, b) - return a + b -end +function add(a, b) return a + b end -function mul(a, b) - return a * b -end +function mul(a, b) return a * b end -function div(a, b) - return a / b -end +function div(a, b) return a / b end -function mod(a, b) - return a % b -end +function mod(a, b) return a % b end -function pow(a, b) - return a ^ b -end +function pow(a, b) return a ^ b end -function unm(a) - return -a -end +function unm(a) return -a end -function concat(a, b) - return a .. b -end +function concat(a, b) return a .. b end -function len(a) - return #a -end +function len(a) return #a end -function eq(a, b) - return a == b -end +function eq(a, b) return a == b end -function lt(a, b) - return a < b -end +function lt(a, b) return a < b end -function le(a, b) - return a <= b -end +function le(a, b) return a <= b end -function index(object, key) - return object[key] -end +function index(object, key) return object[key] end -function newindex(object, key, value) - object[key] = value -end +function newindex(object, key, value) object[key] = value end -function call(object, ...) - object(...) -end +function call(object, ...) object(...) end --- Functional wrappers for logical operators, suffixed with _ to avoid a syntax error +-- Functional wrappers for logical operators, suffixed with _ for syntactical convenience function not_(a) return not a end _ENV["not"] = not_ diff --git a/init.lua b/init.lua index 2e9ef43..7ee18ff 100644 --- a/init.lua +++ b/init.lua @@ -40,6 +40,7 @@ for _, file in pairs{ "schema", "file", "func", + "iterator", "math", "table", "text", diff --git a/iterator.lua b/iterator.lua new file mode 100644 index 0000000..eefeb43 --- /dev/null +++ b/iterator.lua @@ -0,0 +1,78 @@ +local add = modlib.func.add + +--+ For all functions which aggregate over single values, use modlib.table.ivalues - not ipairs - for lists! +--+ Otherwise they will be applied to the indices. +local iterator = {} + +function iterator.range(from, to, step) + if not step then + if not to then + from, to = 1, from + end + step = 1 + end + + return function(_, current) + current = current + step + if current > to then + return + end + return current + end, nil, from - step +end + +function iterator.aggregate(binary_func, total, ...) + for value in ... do + total = binary_func(total, value) + end + return total +end + +function iterator.min(less_than_func, ...) + local min + for value in ... do + if min == nil or less_than_func(value, min) then + min = value + end + end + return min +end + +-- TODO iterator.max + +function iterator.count(...) + local count = 0 + for _ in ... do + count = count + 1 + end + return count +end + +function iterator.sum(...) + return iterator.aggregate(add, 0, ...) +end + +function iterator.average(...) + local count = 0 + local sum = 0 + for value in ... do + count = count + 1 + sum = sum + value + end + return sum / count +end + +--: ... **restartable** iterator +-- A single pass method for calculating the standard deviation exists but is highly inaccurate +function iterator.standard_deviation(...) + local avg = iterator.average(...) + local count = 0 + local sum = 0 + for value in ... do + count = count + 1 + sum = sum + (value - avg)^2 + end + return (sum / count)^.5 +end + +return iterator \ No newline at end of file