Module:Array

Revision as of 20:50, 7 February 2020 by osrsw>Talulah (add take_from)

Documentation for this module may be created at Module:Array/doc

-- <nowiki> awawa
local p = {}

function p.any(enum, fn)
	fn = fn or function(item) return item end
	for _, item in ipairs(enum) do
		if fn(item) then
			return true
		end
	end
	return false
end

function p.all(enum, fn)
	fn = fn or function(item) return item end
	for _, item in ipairs(enum) do
		if not fn(item) then
			return false
		end
	end
	return true
end

function p.each(enum, fn)
	for _, item in ipairs(enum) do
		fn(item)
	end
end

function p.filter(enum, fn)
	fn = fn or function(item) return item end
	local r = {}
	for _, item in ipairs(enum) do
		if fn(item) then
			table.insert(r, item)
		end
	end
	return r
end

function p.find(enum, fn, default)
	for _, item in ipairs(enum) do
		if fn(item) then
			return item
		end
	end
	return default
end

function p.find_index(enum, fn, default)
	for index, item in ipairs(enum) do
		if fn(item) then
			return index
		end
	end
	return default
end

function p.map(enum, fn)
	local r = {}
	for _, item in ipairs(enum) do
		table.insert(r, fn(item))
	end
	return r
end

function p.max_by(enum, fn)
	return p.reduce(enum, function(new, old)
		local y = fn(new)
		return y > old[2] and {new, y} or old
	end, {0, 0})
end

function p.reduce(enum, fn, accumulator)
	local acc = accumulator
	for index, item in ipairs(enum) do
		if index == 1 and not accumulator then
			acc = item
		else
			acc = fn(item, acc)
		end
	end
	return acc
end

function p.reject(enum, fn)
	local r = {}
	for index, item in ipairs(enum) do
		if not fn(item, index) then
			table.insert(r, item)
		end
	end
	return r
end

function p.scan(enum, fn, accumulator)
	local acc = accumulator
	local r = {}
	for index, item in ipairs(enum) do
		if index == 1 and not accumulator then
			acc = item
		else
			acc = fn(item, acc)
		end
		table.insert(r, acc)
	end
	return r
end

function p.slice(enum, start, finish)
	local r = {}
	for index, item in ipairs(enum) do
		if index >= start and index <= finish then
			table.insert(r, item)
		end
	end
	return r
end

function p.split(enum, count)
	if #enum < count then
		return enum, {}
	end

	local x = {}
	local y = {}

	for i = 1, #enum do
		table.insert(
			i <= count and x or y,
			enum[i]
		)
	end
	return x, y
end

function p.sum(enum)
	return p.reduce(enum, function(x, y) return x + y end)
end

function p.take(enum, count)
	local x, _ = p.split(enum, count)
	return x
end

function p.take_every(enum, n)
	local r = {}
	for index, item in ipairs(enum) do
		if (index - 1) % n == 0 then
			table.insert(r, item)
		end
	end
	return r
end

function p.unique(enum)
	local r = {}
	local hash = {}
	for _, item in ipairs(enum) do
		if not hash[item] then
			table.insert(r, item)
			hash[item] = true
		end
	end
	return r
end

function p.zip(enums)
	local r = {}
	local longest = p.max_by(enums, function(enum) return #enum end)
	for i = 1, longest[2] do
		local q = {}
		for j = 1, #enums do
			table.insert(q, enums[j][i])
		end
		table.insert(r, q)
	end
	return r
end

function p.take_from(enum, index, count)
	local x, _ = p.split(p.reject(enum, 
		function(item, idx)
			return idx < index
		end
	), count)
	return x
end

return p
-- </nowiki>