Module:Iterateurs
Ce module ne possède aucune documentation explicative en sous-page, pas même une description succincte.
Vous pouvez créer cette sous-page afin de documenter ce module adéquatement.
Voir les statistiques d'utilisation du module sur l'outil wstat.
La documentation de ce module est générée par le modèle ((Documentation module)).
Les éditeurs peuvent travailler dans le bac à sable (créer).
--[[
---------------------------------------------------------------------------------
-- Iterating primitives
---------------------------------------------------------------------------------
Base functions to work on stateful lua iterators.
Function that creates iterators, like "pair" and "ipair", but stateful unlike them
-- May be building a duplicate of https://www.wikidata.org/wiki/Module:Luafun
--]]
local p = {}
----------------------------------------
-- Copied From Luafun
local methods = {} -- collects the methods to append to an iterator object
local register_method = (function(module, methods)
return function(name, func)
module[name] = func
methods[name] = func
end
end)(p, methods)
-- the metatable for an iterator object
local iterator_mt = {
-- usually called by for-in loop
__call = function(self, param, state)
return self.gen(param, state)
end;
__tostring = function(self)
return '<generator>'
end;
-- add all exported methods
__index = methods;
}
-- used to change an iterator function to an iterator objects to allow to attach methods to an iterator
local wrap = function(gen, param, state)
return setmetatable({
gen = gen,
param = param,
state = state
}, iterator_mt), param, state
end
p.wrap = wrap
local method0 = function(fun)
return function(self)
return fun(self.gen, self.param, self.state)
end
end
local methodn = function(fun)
return function(self, ...)
return fun(self.gen, ...)
end
end
--------------------------------------------------------
-- iterator constructor. Transforms an iterator over a sequence of values in
-- an iterator on the result of the "value_constructor" function applied to the initial values
-- (a kind of an equivalent of the functional "map" function that works on iterator instead of list)
-- this iterator works on values and ignore the keys
local function map(it, transformation)
assert(it, "map : no iterator provided")
return wrap(
function()
local val = it()
if val then return transformation(val) end
end
)
end
register_method("map", map)
-- like "map" except it works on pairs of values (usually key/val pairs)
-- this iterator works on pairs
local function pair_map(it, transformation)
assert(it, "pair_map : no iterator provided")
return wrap(
function()
local i, val = it()
if i then return transformation(i, val) end
end
)
end
register_method("pair_map",pair_map)
-- iterates on the values of another iterators and yield only the values that pass the criteria
-- (a kind of an equivalent of the functional "filter" function that works on iterator instead of list)
-- this iterator works on values
local function filter(it, criteria)
assert(it, "filter : no iterator provided")
assert(type(criteria)=="function", "no criteria provided")
return wrap(
function()
local val = it()
while val and not(criteria(val)) do
val = it()
end
return val
end
)
end
register_method("filter", filter)
-- pair version of the previous function
--this iterators works on pairs
local function pair_filter(it, criteria)
assert(it, "pair_filter : no iterator provided")
return wrap(
function()
local i, val = it()
while val and not(criteria(i, val)) do
i, val = it()
end
return i, val
end
)
end
register_method("pair_filter", pair_filter)
--creates a value only iterator from a "pair" one, yielding only the "keys" (first item of the pair)
--this iterators works on pairs
local function select_keys(it)
assert(it, "select_keys : no iterator provided")
return wrap(
function()
local i, val = it()
return i
end
)
end
register_method("select_keys", select_keys)
--creates a value only iterator from a "pair" one, yielding only the "values" (second item of the pair)
--this iterators works on pairs
local function select_vals(it)
assert(it, "pair_vals : no iterator provided")
return wrap(
function()
local i, val = it()
return val
end
)
end
p.select_vals = select_vals
-- create a stateful iterators that iterates on the values of a table
-- (from the stateless standard "pairs" iterator on tables)
local function on_vals(tabl)
local _f, _s, _v = pairs(tabl)
return wrap(
function()
if _s then
local i, res = _f(_s, _v)
_v = i
if not res then _s = nil end
return res
end
end
)
end
p.on_vals = on_vals
-- create a stateful iterators that iterates over the keys of a table
-- (from the stateless standard "pairs" iterator on tables)
local function on_pairs(tabl)
local _f, _s, _v = pairs(tabl)
return --wrap(
function()
if _s then
local i, res = _f(_s, _v)
_v = i
if not res then _s = nil end
return i, res
end
end
--)
end
p.on_pairs = on_pairs
-- equivalent of the "join" operation, with join((("a"},{},{"b","c"))) = {"a","b","c"}
-- for iterators.
-- if the parameter "it" is an iterator that yields {"a"} ; then {} ; then {"b","c"}
-- and "creator" is a function that creates an iterator that yields "b" then "c" from the table {"b","c"}
-- the "flatten"-ing of this parameter will yield "a" then "b" then "c"
local function flatten(it, creator)
assert(it, "flatten : no iterator provided")
assert(creator, "flatten : no iterator creator provided")
local main_val = it()
if main_val then
local sub_it = creator(main_val)
return wrap(
function()
if main_val then
local val = nil
while not val and main_val do
if sub_it then
val = sub_it()
end
if not val then
main_val = it()
if not main_val then return end
sub_it = creator(main_val)
end
end
return val
end
end
)
else
return wrap(function () return nil end)
end
end
register_method("flatten", flatten)
-- equivalent of list concatenation for iterators
local chain = function (it1, it2)
return wrap(
function()
local res = it1() or it2()
return res
end
)
end
register_method("chain", chain)
-- creates an iterator on a single value
p.singleton = function (val)
local iterated
return wrap(function()
if not iterated then
iterated = true
return val
end
end)
end
local function fold(it, acc, init)
local accum = init
for res in it do
accum = acc(res, accum)
end
return accum
end
register_method("fold", fold)
local function totable(it)
return fold(
it,
function (val, tabl)
table.insert(tabl, val)
return tabl
end,
{}
)
end
register_method("totable", totable)
function p.range(start_i, end_i, step)
local i = nil
step = step or 1
assert(step ~= 0)
local direction = step/math.abs(step)
return wrap(function()
if not i then
i = start_i
else
i = i + step
end
if i * direction < end_i * direction then
return i
else
return
end
end)
end
--------------------------------------------------------------------------------
-- TESTING FUNCTIONS
--------------------------------------------------------------------------------
function p.execute(iterator)
for x in iterator do
mw.log(x)
end
end
function p.execute_pair(iterator)
for x, y in iterator do
mw.log(x, y)
end
end
return p
Text is available under the CC BY-SA 4.0 license; additional terms may apply.
Images, videos and audio are available under their respective licenses.