Module:Iterateurs

Cette page fait l’objet d’une mesure de semi-protection étendue.
Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 19 novembre 2016 à 16:55 et modifiée en dernier par TomT0m (discuter | contributions). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)

 Documentation[créer] [purger]
--[[
---------------------------------------------------------------------------------
-- 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 = {}


-- 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)
	return function()
		local val = it()
		if val then return transformation(val) end
	end
end

p.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)
	return function()
		local i, val = it()
		if i then return transformation(i, val) end
	end
end

p.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)
	return function()
		local val = it()
		while val and not(criteria(val)) do
			val = it()
		end
		return val
	end
end

p.filter = filter

-- pair version of the previous function

--this iterators works on pairs
local function pair_filter(it, criteria)
	return function()
		local i, val = it()
		while val and not(criteria(i, val)) do
			i, val = it()
		end
		return i, val
	end
end

p.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)
	return function()
		local i, val = it()
		return i
	end
end

p.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)
	return 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 function()
		if _s then
			local i, res = _f(_s, _v)
			_v = i
			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 function()
		if _s then
			local i, res = _f(_s, _v)
			_v = i
			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)
	local main_val = it()
	
	if main_val then
		local sub_it = creator(main_val)
		return 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
	end
end

p.flatten = flatten

--[[
Test expression : p.execute(p.flatten(p.on_vals({{"plop", "plop"}, {}, {"plop"}}), p.on_vals)) 
expected :        "plop"\n"plop"\n"plop

Test expression : p.execute(p.pair_map(p.on_pairs({"1", "2"}), function(x, y) return 2*y end))
expected :        "2"\n"4"
--]]


--------------------------------------------------------------------------------
-- 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