Documentation for this module may be created at Modulu:extra/dok

local extra = {
	string = {},
	table = {},
}

function extra.string.find(s, t, index, value, key)
	local tRes = {}
	if not (value or key) then
		value = true
	end
	index = tonumber(index) or 1
	if not (type(t) == type({})) then
		t = {t}
	end
	if extra.table.indexnonnumeric(t) then
		t = {t}
	end
	if s == nil then
		s = ""
	end
	for iSub, tSub in pairs(t) do
		local sIndex = string.sub(tostring(s), index) or ""
		if not (type(tSub) == type({})) then
			tSub = {tSub}
		end
		for i, v in pairs(tSub) do
			if key and string.find(sIndex, tostring(i)) then
				local tI = {string.find(sIndex, tostring(i))}
				if tRes[iSub] then
					if (tRes[iSub][4] > tI[1]) or (
						(tRes[iSub][4] == tI[1]) and (tRes[iSub][5] < tI[2])
					) then
						tRes[iSub] = {i, i, v, tI[1], tI[2]}
					end
				else
					tRes[iSub] = {i, i, v, tI[1], tI[2]}
				end
			end
			if value and string.find(sIndex, tostring(v)) then
				local tV = {string.find(sIndex, tostring(v))}
				if tRes[iSub] then
					if (tRes[iSub][4] > tV[1]) or (
						(tRes[iSub][4] == tV[1]) and (tRes[iSub][5] < tV[2])
					) then
						tRes[iSub] = {i, v, v, tV[1], tV[2]}
					end
				else
					tRes[iSub] = {i, v, v, tV[1], tV[2]}
				end
			end
		end
		if tRes[iSub] then
			index = tRes[iSub][5] + 1
		else
			return tRes
		end
	end
	return tRes
end

function extra.table.chain(...)
	local t = {}
	for i = 1, #({...}) do
		local tT = (type(({...})[i]) == type({})) and ({...})[i] or {({...})[i]}
		tT = (
			function(t) -- appends the "unnumbered" values after the "numbered" values
				local tRes = {}
				t = (type(t) == type({})) and t or {t}
				for i, v in ipairs(t) do
					tRes[i] = v
				end
				for i, v in pairs(t) do
					if tRes[i] == nil then
						tRes[#tRes + 1] = v
					end
				end
				return tRes
			end
		)(tT)
		for i = 1, #tT do
			t[#t + 1] = tT[i]
		end
	end
	return t
end

function extra.table.countdepth(t, recursions)
	local tRec = {
		[t] = 0,
	}
	recursions = (
		type(recursions) == type(0)
	) and (
		recursions > 0
	) and recursions or 0
	local function count(t)
		local n = 0
		t = type(t) == type({}) and t or {}
		for i, v in pairs(t) do
			if type(v) == type({}) then
				tRec[v] = tRec[v] and (tRec[v] + 1) or 0
				n = math.max(n, (tRec[v] <= recursions) and (count(v) + 1) or 1)
			end
		end
		return n
	end
	return count(t)
end

function extra.table.countsubs(t, recursions)
	local tRec = {
		[t] = 0,
	}
	recursions = (
		type(recursions) == type(0)
	) and (
		recursions > 0
	) and recursions or 0
	local function count(t)
		local n = 0
		t = type(t) == type({}) and t or {}
		for i, v in pairs(t) do
			if type(v) == type({}) then
				tRec[v] = tRec[v] and (tRec[v] + 1) or 0
				n = n + (
					(tRec[v] <= recursions) and math.max(count(v), 1) or
					1
				)
			end
		end
		return n
	end
	return count(t)
end

function extra.table.cover(...)
	local t = {}
	local tArg = {...}
	for iT, vT in pairs(tArg) do
		if type(vT) == type({}) then
			for i, v in pairs(vT) do
				t[i] = v
			end
		end
	end
	return t
end

function extra.table.find(t, value)
	if not (type(t) == type({})) then
		t = {t}
	end
	for i, v in pairs(t) do
		if v == value then
			return i
		end
	end
	return nil
end

function extra.table.indexnonnumeric(t)
	if type(t) == type({}) then
		for i in pairs(t) do
			if not (type(i) == type(0)) then
				return true
			end
		end
	end
	return false
end

function extra.table.listindex(t)
	local tRes = {}
	if not (type(t) == type({})) then
		t = {t}
	end
	for i in pairs(t) do
		tRes[#tRes + 1] = i
	end
	return tRes
end

function extra.table.multiindex(...)
	local v = nil
	for i = 1, #{...} do
		if (v == nil) then
			v = ({...})[i]
		else
			if type(v) == type({}) then
				v = v[({...})[i]]
				if v == nil then
					return nil
				end
			else
				return nil
			end
		end
	end
	return v
end

function extra.table.uniquify(t)
	local tRes = type(t) == type({}) and t or {t}
	t = {}
	for i, v in pairs(tRes) do
		t[v] = t[v] or i
	end
	tRes = {}
	for i, v in pairs(t) do
		tRes[v] = tRes[v] or i
	end
	return tRes
end

return extra