106 lines
1.6 KiB
Lua
106 lines
1.6 KiB
Lua
local iterators = {}
|
|
|
|
function iterators.range(...)
|
|
local a, b, c = ...
|
|
if type(a) ~= "number" then
|
|
error("invalid range")
|
|
end
|
|
if not b then
|
|
a, b = 1, a
|
|
end
|
|
if type(b) ~= "number" then
|
|
error("invalid range")
|
|
end
|
|
c = c or 1
|
|
if type(c) ~= "number" or c == 0 then
|
|
error("invalid range")
|
|
end
|
|
|
|
if c > 0 then
|
|
return function()
|
|
if a > b then
|
|
return
|
|
end
|
|
local to_return = a
|
|
a = a + c
|
|
return to_return
|
|
end
|
|
else
|
|
return function()
|
|
if a < b then
|
|
return
|
|
end
|
|
local to_return = a
|
|
a = a + c
|
|
return to_return
|
|
end
|
|
end
|
|
end
|
|
|
|
function iterators.repeat_(value, times)
|
|
if times then
|
|
local i = 0
|
|
return function()
|
|
i = i + 1
|
|
if i <= times then
|
|
return value
|
|
end
|
|
end
|
|
else
|
|
return function()
|
|
return value
|
|
end
|
|
end
|
|
end
|
|
|
|
function iterators.chain(...)
|
|
local arg = { ... }
|
|
local i = 1
|
|
|
|
return function()
|
|
while i <= #arg do
|
|
local v = arg[i]()
|
|
if v then
|
|
return v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function iterators.count(start, step)
|
|
step = step or 1
|
|
return function()
|
|
local rv = start
|
|
start = start + step
|
|
return rv
|
|
end
|
|
end
|
|
|
|
function iterators.values(t)
|
|
local k
|
|
return function()
|
|
local value
|
|
k, value = next(t, k)
|
|
return value
|
|
end
|
|
end
|
|
|
|
function iterators.accumulate(t, composer, initial)
|
|
local value = initial
|
|
local i = futil.table.iterate(t)
|
|
return function()
|
|
local next_value = i()
|
|
if next_value then
|
|
if value == nil then
|
|
value = next_value
|
|
elseif composer then
|
|
value = composer(value, next_value)
|
|
else
|
|
value = value + next_value
|
|
end
|
|
return value
|
|
end
|
|
end
|
|
end
|
|
|
|
futil.iterators = iterators
|