Module:Stream

盐棋讨论 | 贡献2022年10月19日 (三) 02:22的版本 (Module:Stream)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

可在Module:Stream/doc创建此模块的帮助文档

local p = {}

function p:map(fn)
	local o = setmetatable({}, { __index = p })
	local prev = self
	function o.find()
		local k, v = prev.find()
		if k ~= nil then return k, fn(v) end
	end
	return o
end

function p:filter(fn)
	local o = setmetatable({}, { __index = p })
	local prev = self
	function o.find()
		local k, v
		repeat k, v = prev.find() until k == nil or fn(v)
		return k, v
	end
	return o
end

function p:flatMap(fn)
	local o = setmetatable({}, { __index = p })
	local prev = self
	local sub = p.empty()
	function o.find()
		local k, v
		while true do
			k, v = sub.find()
			if k ~= nil then return k, v end
			k, v = prev.find()
			if k == nil then return end
			sub = fn(v)
		end
	end
	return o
end

function p:peek(fn)
	local o = setmetatable({}, { __index = p })
	local prev = self
	function o.find()
		local k, v = prev.find()
		if k ~= nil then fn(v) end
		return k, v
	end
	return o
end

function p:reduce(fn, i)
	if i == nil then
		local k
		k, i = self.find()
		if k == nil then return end
	end
	for _, v in self.find do
		i = fn(i, v)
	end
	return i
end

function p:toArray()
	local o = {}
	for _, v in self.find do
		table.insert(o, v)
	end
	return o
end

function p:sorted(fn)
	local o = self:toArray()
	table.sort(o, fn)
	return p.Array(o)
end

function p.empty()
	local o = setmetatable({}, { __index = p })
	function o.find() end
	return o
end

function p.concat(first, second)
	local o = setmetatable({}, { __index = p })
	local focus = first
	function o.find()
		local k, v = focus.find()
		if k == nil and focus == first then
			focus = second
			k, v = focus.find()
		end
		return k, v
	end
	return o
end

function p.Array(array)
	local o = setmetatable({}, { __index = p })
	local inv = 0
	function o.find()
		local k = inv + 1
		if array[k] ~= nil then inv = k else return end
		return k, array[k]
	end
	return o
end

function p.Set(set)
	local o = setmetatable({}, { __index = p })
	local inv
	function o.find()
		k = next(set, inv)
		if k ~= nil then inv = k end
		return k and true, k
	end
	return o
end

function p.Map(map)
	local o = setmetatable({}, { __index = p })
	local inv
	function o.find()
		local k, v = next(map, inv)
		if k ~= nil then inv = k end
		return k and true, { k, v }
	end
	return o
end

return p