From f06bda97851046481ecf67a479f2bb9dab5212ef Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Sat, 13 Nov 2021 17:58:40 +0100 Subject: [PATCH] Add iterator aggregation functions --- func.lua | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/func.lua b/func.lua index 5128ae3..11405a9 100644 --- a/func.lua +++ b/func.lua @@ -1,6 +1,6 @@ -- Localize globals -local error, coroutine, modlib, unpack - = error, coroutine, modlib, unpack +local error, coroutine, math, modlib, unpack + = error, coroutine, math, modlib, unpack -- Set environment local _ENV = {} @@ -78,6 +78,62 @@ 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(...)