For faster navigation, this Iframe is preloading the Wikiwand page for Module:Iterateurs.

Module:Iterateurs

 Documentation[créer] [purger]

Voir les statistiques d'utilisation du module sur l'outil wstat.

--[[
---------------------------------------------------------------------------------
-- 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
{{bottomLinkPreText}} {{bottomLinkText}}
Module:Iterateurs
Listen to this article

This browser is not supported by Wikiwand :(
Wikiwand requires a browser with modern capabilities in order to provide you with the best reading experience.
Please download and use one of the following browsers:

This article was just edited, click to reload
This article has been deleted on Wikipedia (Why?)

Back to homepage

Please click Add in the dialog above
Please click Allow in the top-left corner,
then click Install Now in the dialog
Please click Open in the download dialog,
then click Install
Please click the "Downloads" icon in the Safari toolbar, open the first download in the list,
then click Install
{{::$root.activation.text}}

Install Wikiwand

Install on Chrome Install on Firefox
Don't forget to rate us

Tell your friends about Wikiwand!

Gmail Facebook Twitter Link

Enjoying Wikiwand?

Tell your friends and spread the love:
Share on Gmail Share on Facebook Share on Twitter Share on Buffer

Our magic isn't perfect

You can help our automatic cover photo selection by reporting an unsuitable photo.

This photo is visually disturbing This photo is not a good choice

Thank you for helping!


Your input will affect cover photo selection, along with input from other users.