马骝是什么意思| 解脲脲原体阳性吃什么药| 一毛不拔是什么动物| 涵字取名的寓意是什么| 做核磁共振挂什么科| 经常耳鸣是为什么| 人长寿的秘诀是什么| 肠胃炎吃什么食物| 肛门周围痒是什么病| 什么叫根管治疗| 肌酐高吃什么好| 白兰地是什么酒| 人造革是什么材质| 起水泡痒是什么原因| 柳树代表什么生肖| 农垦局是什么性质单位| 为什么会得骨癌| 清真食品是什么意思| 黄鳝喜欢吃什么| 半夜口渴是什么原因| 打封闭是什么意思| 什么往什么来| 乳腺结节摸着什么感觉| 三四月份是什么星座| 一九七二年属什么生肖| 可尔必思是什么饮料| 单侧耳鸣是什么原因引起的| 如花是什么意思| 灰色是什么颜色调出来的| 阴囊潮湿吃什么药好| 中医科是看什么病的| 中期唐氏筛查查什么| 支教是什么意思| 毒唯是什么意思| hill什么意思| 尿酸高可以喝什么饮料| 姹什么嫣什么| 11.18是什么星座| 梦见被狗咬是什么意思| 勿忘心安是什么意思| 橄榄菜长什么样子图片| 一见什么| 靴靴是什么意思| 栩字五行属什么| 最难做的饭是什么| 丹参有什么功效| 感冒发烧能吃什么水果| 梭子蟹什么季节吃最好| 不什么不什么的词语| 谷丙转氨酶高是什么原因| 腊肉炒什么最好吃| 丝瓜有什么好处| leep是什么手术| 马齿苋不能和什么一起吃| eu是什么元素| 什么颜色可以调成红色| 什么是小三阳| 做梦梦到水是什么征兆| 旗舰店什么意思| 血府逐瘀片主治什么病| pp材质和ppsu材质有什么区别| 家道中落是什么意思| 办身份证需要准备什么| 宝石蓝配什么颜色好看| 猪八戒姓什么| 白化病是什么原因引起的| 南昌有什么好玩的| 阳历三月是什么星座| 痔疮有什么特征| 小孩舌头发白什么原因| 身痒是什么原因引起的| 药引子是什么意思| 柠檬黄配什么颜色好看| 谈情说爱是什么意思| 阴道吹气是什么原因| 高职本科什么意思| 人工受孕和试管婴儿有什么区别| 体内湿气重吃什么药| 身上起红疙瘩是什么| 支气管炎吃什么药| 肛裂出血和痔疮出血有什么区别| 529是什么意思| 红绿色盲是什么遗传病| 发端是什么意思| 减肥吃什么| 胃得宁又叫什么名字| 驿马星是什么意思| 机关单位和事业单位有什么区别| 葛仙米是什么| 梦见屎是什么预兆| 治疗风湿有什么好方法| 弥漫性病变是什么意思| 甲钴胺治疗什么病| 鸭嘴鱼吃什么食物| 铁观音属于什么茶| 白醋泡脚有什么效果| mfr是什么意思| 油光满面是什么意思| 清华什么专业最好| up是什么意思| 棉花是什么时候传入中国的| 争奇斗艳的斗是什么意思| 夫妻都是b型血孩子是什么血型| lch是什么意思| 2009年属什么生肖| 夏天防中暑备什么药| 窦性心律室性早搏是什么意思| 各类病原体dna测定是检查什么| 肾功能检查挂什么科| 中国的国花是什么| 12年一个轮回叫什么| 傍晚是什么时辰| 左下腹疼挂什么科| 脸部浮肿是什么原因| 嫁妆是什么意思| 黍米是什么米| 肠胃炎拉肚子吃什么药| 马是什么牌子的车| 医院打耳洞挂什么科| 收口是什么意思| 中药什么时候喝效果最好| 陶弘景有什么之称| 处女是什么象星座| 大腿青筋明显是什么原因| 日昳是什么意思| 尿比重偏高是什么原因| 重情重义是什么意思| 安徽属于什么地区| 五月十二是什么星座| 脑白质脱髓鞘吃什么药| 圣水是什么| 石头五行属什么| 梦见自己尿裤子了是什么意思| 更年期什么意思| 狼吞虎咽的意思是什么| 房产税什么时候开始征收| 串联质谱筛查是什么病| 12月27号是什么星座| 什么是逆商| 妇科臭氧治疗是什么| 上火吃什么| 赤潮是什么意思| 坐落是什么意思| 4月10日什么星座| 精分什么意思| 猫的眼睛晚上为什么会发光| 天龙八部是指佛教中的什么| 抑菌是什么意思| 端午节吃什么菜呢| 不睡人的空床放点什么| 去美容院洗脸有什么好处| 耳鼻喉科主要看什么病| 清宫和无痛人流有什么区别| 两横两竖是什么字| 容易水肿是什么原因| 2006年出生属什么| 躺平是什么意思| 身正不怕影子斜是什么意思| 烘焙是什么意思| 头疗是什么| 食指是什么经络| 凸起的痣是什么痣| 祎是什么意思| 痔疮吃什么药最好| 鹭鸶是什么动物| 感觉牙齿松动是什么原因| 做放疗的人吃什么好| 叶黄素是什么| 银屑病为什么会自愈| ein是什么牌子| 梦见蛇咬别人是什么意思| 囊肿里面是什么东西| 世界上最毒的蜘蛛叫什么| 愚昧什么意思| 白塞氏是一种什么病| 女生左手食指戴戒指什么意思| 治疗带状疱疹用什么药最好| 梦见穿破鞋是什么意思| 产妇吃什么好| 梦见香蕉是什么意思| pornhub是什么| 胃酸分泌过多吃什么药| 狗吃什么蔬菜好| 兰花长什么样| 什么的夏天| 提高免疫力吃什么药| 左肺下叶纤维灶是什么意思| 脑脊液是什么颜色| 牙根疼吃什么药最好| 子午相冲是什么生肖| 孩子脾虚内热大便干吃什么药| 酸菜鱼放什么配菜好吃| 白泽长什么样| 杨梅有什么功效| 银子有什么功效与作用| tc版是什么意思| 结节状高密度影是什么意思| cc是什么| 难为你了是什么意思| 腰酸痛挂什么科| 为什么会胸闷| snoopy是什么意思| 脸一边大一边小是什么原因| 内心独白什么意思| 88是什么意思| 八字华盖是什么意思| roa是什么| 什么饮料解酒| 公丁香和母丁香有什么区别| 囤货是什么意思| 什么是处女膜| 英雄联盟msi是什么| 树欲静而风不止什么意思| 咩是什么意思| 白腊金是什么意思| 眼睛发粘是什么原因| 想做肠镜挂什么科| 什么原因会引起胎停| 林彪为什么叛逃| 舌头上有红点点是什么原因| 黄瓜籽有什么功效| 牛的五行属什么| 眼睛周围长斑是什么原因引起的| 高血压高血糖能吃什么水果| 一年四季穿棉衣是什么生肖| 两岁宝宝不会说话但什么都知道| 每天喝酸奶有什么好处和坏处| 高考300分能上什么大学| 阿奇霉素治疗什么| 肘关节发黑是什么原因| 2019什么年| 男士脸黑用什么能美白| 女性喝什么茶最好| 糖皮质激素是什么| 梅毒长什么样子| 做梦梦见僵尸是什么预兆| 戒指戴哪个手指代表什么| 如期是什么意思| 洛基是什么神| 乳腺是什么科| 多吃海带有什么好处和坏处| 小朋友膝盖疼是什么原因| 万圣节什么时候| 胆囊息肉挂什么科| 肌酸激酶是什么| 一九九八年属什么生肖| 白巧克力是什么做的| 跖围是什么意思| 九月九日是什么节日| 榴莲什么时候吃最好| 女人喝甘草水有什么好处| 偶尔耳鸣是什么原因| 晚上20点是什么时辰| 什么情况下需要会诊| 肾功能不好有什么症状| ins风格是什么| 头昏和头晕有什么区别| 吃什么补脾虚| 伏特加是什么意思| 张良属什么生肖| 糖尿病可以吃什么水果| 软著是什么| dickies是什么牌子| 巫婆是什么意思| 百度Jump to content

?????????????
百度 当前,大连正在面对严峻的森林防火形势。

This module includes a number of functions for dealing with Lua tables. It is a meta-module, meant to be called from other Lua modules, and should not be called directly from #invoke.

Loading the module

To use any of the functions, first you must load the module.

local TableTools = require('Module:TableTools')

isPositiveInteger

TableTools.isPositiveInteger(value)

Returns true if value is a positive integer, and false if not. Although it doesn't operate on tables, it is included here as it is useful for determining whether a given table key is in the array part or the hash part of a table.

isNan

TableTools.isNan(value)

Returns true if value is a NaN value, and false if not. Although it doesn't operate on tables, it is included here as it is useful for determining whether a value can be a valid table key. (Lua will generate an error if a NaN value is used as a table key.)

shallowClone

TableTools.shallowClone(t)

Returns a clone of a table. The value returned is a new table, but all subtables and functions are shared. Metamethods are respected, but the returned table will have no metatable of its own. If you want to make a new table with no shared subtables and with metatables transferred, you can use mw.clone instead. If you want to make a new table with no shared subtables and without metatables transferred, use deepCopy with the noMetatable option.

removeDuplicates

TableTools.removeDuplicates(t)

Removes duplicate values from an array. This function is only designed to work with standard arrays: keys that are not positive integers are ignored, as are all values after the first nil value. (For arrays containing nil values, you can use compressSparseArray first.) The function tries to preserve the order of the array: the earliest non-unique value is kept, and all subsequent duplicate values are removed. For example, for the table {5, 4, 4, 3, 4, 2, 2, 1} removeDuplicates will return {5, 4, 3, 2, 1}.

numKeys

TableTools.numKeys(t)

Takes a table t and returns an array containing the numbers of any positive integer keys that have non-nil values, sorted in numerical order. For example, for the table {'foo', nil, 'bar', 'baz', a = 'b'}, numKeys will return {1, 3, 4}.

affixNums

TableTools.affixNums(t, prefix, suffix)

Takes a table t and returns an array containing the numbers of keys with the optional prefix prefix and the optional suffix suffix. For example, for the table {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix 'a', affixNums will return {1, 3, 6}. All characters in prefix and suffix are interpreted literally.

numData

TableTools.numData(t, compress)

Given a table with keys like "foo1", "bar1", "foo2", and "baz2", returns a table of subtables in the format { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }. Keys that don't end with an integer are stored in a subtable named "other". The compress option compresses the table so that it can be iterated over with ipairs.

compressSparseArray

TableTools.compressSparseArray(t)

Takes an array t with one or more nil values, and removes the nil values while preserving the order, so that the array can be safely traversed with ipairs. Any keys that are not positive integers are removed. For example, for the table {1, nil, foo = 'bar', 3, 2}, compressSparseArray will return {1, 3, 2}.

sparseIpairs

TableTools.sparseIpairs(t)

This is an iterator function for traversing a sparse array t. It is similar to ipairs, but will continue to iterate until the highest numerical key, whereas ipairs may stop after the first nil value. Any keys that are not positive integers are ignored.

Usually sparseIpairs is used in a generic for loop.

for i, v in TableTools.sparseIpairs(t) do
   -- code block
end

Note that sparseIpairs uses the pairs function in its implementation. Although some table keys appear to be ignored, all table keys are accessed when it is run.

size

TableTools.size(t)

Finds the size of a key/value pair table. For example, for the table {foo = 'foo', bar = 'bar'}, size will return 2. The function will also work on arrays, but for arrays it is more efficient to use the # operator. Note that to find the table size, this function uses the pairs function to iterate through all of the table keys.

keysToList

TableTools.keysToList(t, keySort, checked)

Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function, which follows the same rules as the comp function supplied to table.sort. If keySort is false, no sorting is done. Set checked to true to skip the internal type checking.

sortedPairs

TableTools.sortedPairs(t, keySort)

Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient.

isArray

TableTools.isArray(value)

Returns true if value is a table and all keys are consecutive integers starting at 1.

isArrayLike

TableTools.isArrayLike(value)

Returns true if value is iterable and all keys are consecutive integers starting at 1.

invert

TableTools.invert(arr)

Transposes the keys and values in an array. For example, invert{ "a", "b", "c" } yields { a=1, b=2, c=3 }.

listToSet

TableTools.listToSet(arr)

Creates a set from the array part of the table arr. Indexing the set by any of the values of the array returns true. For example, listToSet{ "a", "b", "c" } yields { a=true, b=true, c=true }. See also Module:Lua set for more advanced ways to create a set.

deepCopy

TableTools.deepCopy(orig, noMetatable, alreadySeen)

Creates a copy of the table orig. As with mw.clone, all values that are not functions are duplicated and the identity of tables is preserved. If noMetatable is true, then the metatable (if any) is not copied. Can copy tables loaded with mw.loadData.

Similar to mw.clone, but mw.clone cannot copy tables loaded with mw.loadData and does not allow metatables not to be copied.

sparseConcat

TableTools.sparseConcat(t, sep, i, j)

Concatenates all values in the table that are indexed by a positive integer, in order. For example, sparseConcat{ "a", nil, "c", "d" } yields "acd" and sparseConcat{ nil, "b", "c", "d" } yields "bcd".

length

TableTools.length(t, prefix)

Finds the length of an array or of a quasi-array with keys with an optional prefix such as "data1", "data2", etc. It uses an exponential search algorithm to find the length, so as to use as few table lookups as possible.

This algorithm is useful for arrays that use metatables (e.g. frame.args) and for quasi-arrays. For normal arrays, just use the # operator, as it is implemented in C and will be quicker.

inArray

TableTools.inArray(arr, valueToFind)

Returns true if valueToFind is a member of the array arr, and false otherwise.


------------------------------------------------------------------------------------
--                                   TableTools                                   --
--                                                                                --
-- This module includes a number of functions for dealing with Lua tables.        --
-- It is a meta-module, meant to be called from other Lua modules, and should not --
-- be called directly from #invoke.                                               --
------------------------------------------------------------------------------------

local libraryUtil = require('libraryUtil')

local p = {}

-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti

------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
function p.isPositiveInteger(v)
	return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity
end

------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false if
-- not. Although it doesn't operate on tables, it is included here as it is useful
-- for determining whether a value can be a valid table key. Lua will generate an
-- error if a NaN is used as a table key.
------------------------------------------------------------------------------------
function p.isNan(v)
	return type(v) == 'number' and v ~= v
end

------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
function p.shallowClone(t)
	checkType('shallowClone', 1, t, 'table')
	local ret = {}
	for k, v in pairs(t) do
		ret[k] = v
	end
	return ret
end

------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
function p.removeDuplicates(arr)
	checkType('removeDuplicates', 1, arr, 'table')
	local isNan = p.isNan
	local ret, exists = {}, {}
	for _, v in ipairs(arr) do
		if isNan(v) then
			-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
			ret[#ret + 1] = v
		elseif not exists[v] then
			ret[#ret + 1] = v
			exists[v] = true
		end
	end
	return ret
end

------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
function p.numKeys(t)
	checkType('numKeys', 1, t, 'table')
	local isPositiveInteger = p.isPositiveInteger
	local nums = {}
	for k in pairs(t) do
		if isPositiveInteger(k) then
			nums[#nums + 1] = k
		end
	end
	table.sort(nums)
	return nums
end

------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will return
-- {1, 3, 6}.
------------------------------------------------------------------------------------
function p.affixNums(t, prefix, suffix)
	checkType('affixNums', 1, t, 'table')
	checkType('affixNums', 2, prefix, 'string', true)
	checkType('affixNums', 3, suffix, 'string', true)

	local function cleanPattern(s)
		-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
		return s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
	end

	prefix = prefix or ''
	suffix = suffix or ''
	prefix = cleanPattern(prefix)
	suffix = cleanPattern(suffix)
	local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'

	local nums = {}
	for k in pairs(t) do
		if type(k) == 'string' then
			local num = mw.ustring.match(k, pattern)
			if num then
				nums[#nums + 1] = tonumber(num)
			end
		end
	end
	table.sort(nums)
	return nums
end

------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like {"foo1", "bar1", "foo2", "baz2"}, returns a table
-- of subtables in the format
-- {[1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'}}.
-- Keys that don't end with an integer are stored in a subtable named "other". The
-- compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
function p.numData(t, compress)
	checkType('numData', 1, t, 'table')
	checkType('numData', 2, compress, 'boolean', true)
	local ret = {}
	for k, v in pairs(t) do
		local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
		if num then
			num = tonumber(num)
			local subtable = ret[num] or {}
			if prefix == '' then
				-- Positional parameters match the blank string; put them at the start of the subtable instead.
				prefix = 1
			end
			subtable[prefix] = v
			ret[num] = subtable
		else
			local subtable = ret.other or {}
			subtable[k] = v
			ret.other = subtable
		end
	end
	if compress then
		local other = ret.other
		ret = p.compressSparseArray(ret)
		ret.other = other
	end
	return ret
end

------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
function p.compressSparseArray(t)
	checkType('compressSparseArray', 1, t, 'table')
	local ret = {}
	local nums = p.numKeys(t)
	for _, num in ipairs(nums) do
		ret[#ret + 1] = t[num]
	end
	return ret
end

------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
function p.sparseIpairs(t)
	checkType('sparseIpairs', 1, t, 'table')
	local nums = p.numKeys(t)
	local i = 0
	local lim = #nums
	return function ()
		i = i + 1
		if i <= lim then
			local key = nums[i]
			return key, t[key]
		else
			return nil, nil
		end
	end
end

------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
function p.size(t)
	checkType('size', 1, t, 'table')
	local i = 0
	for _ in pairs(t) do
		i = i + 1
	end
	return i
end

local function defaultKeySort(item1, item2)
	-- "number" < "string", so numbers will be sorted before strings.
	local type1, type2 = type(item1), type(item2)
	if type1 ~= type2 then
		return type1 < type2
	elseif type1 == 'table' or type1 == 'boolean' or type1 == 'function' then
		return tostring(item1) < tostring(item2)
	else
		return item1 < item2
	end
end
------------------------------------------------------------------------------------
-- keysToList
--
-- Returns an array of the keys in a table, sorted using either a default
-- comparison function or a custom keySort function.
------------------------------------------------------------------------------------
function p.keysToList(t, keySort, checked)
	if not checked then
		checkType('keysToList', 1, t, 'table')
		checkTypeMulti('keysToList', 2, keySort, {'function', 'boolean', 'nil'})
	end

	local arr = {}
	local index = 1
	for k in pairs(t) do
		arr[index] = k
		index = index + 1
	end

	if keySort ~= false then
		keySort = type(keySort) == 'function' and keySort or defaultKeySort
		table.sort(arr, keySort)
	end

	return arr
end

------------------------------------------------------------------------------------
-- sortedPairs
--
-- Iterates through a table, with the keys sorted using the keysToList function.
-- If there are only numerical keys, sparseIpairs is probably more efficient.
------------------------------------------------------------------------------------
function p.sortedPairs(t, keySort)
	checkType('sortedPairs', 1, t, 'table')
	checkType('sortedPairs', 2, keySort, 'function', true)

	local arr = p.keysToList(t, keySort, true)

	local i = 0
	return function ()
		i = i + 1
		local key = arr[i]
		if key ~= nil then
			return key, t[key]
		else
			return nil, nil
		end
	end
end

------------------------------------------------------------------------------------
-- isArray
--
-- Returns true if the given value is a table and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArray(v)
	if type(v) ~= 'table' then
		return false
	end
	local i = 0
	for _ in pairs(v) do
		i = i + 1
		if v[i] == nil then
			return false
		end
	end
	return true
end

------------------------------------------------------------------------------------
-- isArrayLike
--
-- Returns true if the given value is iterable and all keys are consecutive
-- integers starting at 1.
------------------------------------------------------------------------------------
function p.isArrayLike(v)
	if not pcall(pairs, v) then
		return false
	end
	local i = 0
	for _ in pairs(v) do
		i = i + 1
		if v[i] == nil then
			return false
		end
	end
	return true
end

------------------------------------------------------------------------------------
-- invert
--
-- Transposes the keys and values in an array. For example, {"a", "b", "c"} ->
-- {a = 1, b = 2, c = 3}. Duplicates are not supported (result values refer to
-- the index of the last duplicate) and NaN values are ignored.
------------------------------------------------------------------------------------
function p.invert(arr)
	checkType("invert", 1, arr, "table")
	local isNan = p.isNan
	local map = {}
	for i, v in ipairs(arr) do
		if not isNan(v) then
			map[v] = i
		end
	end

	return map
end

------------------------------------------------------------------------------------
-- listToSet
--
-- Creates a set from the array part of the table. Indexing the set by any of the
-- values of the array returns true. For example, {"a", "b", "c"} ->
-- {a = true, b = true, c = true}. NaN values are ignored as Lua considers them
-- never equal to any value (including other NaNs or even themselves).
------------------------------------------------------------------------------------
function p.listToSet(arr)
	checkType("listToSet", 1, arr, "table")
	local isNan = p.isNan
	local set = {}
	for _, v in ipairs(arr) do
		if not isNan(v) then
			set[v] = true
		end
	end

	return set
end

------------------------------------------------------------------------------------
-- deepCopy
--
-- Recursive deep copy function. Preserves identities of subtables.
------------------------------------------------------------------------------------
local function _deepCopy(orig, includeMetatable, already_seen)
	if type(orig) ~= "table" then
		return orig
	end
	
	-- already_seen stores copies of tables indexed by the original table.
	local copy = already_seen[orig]
	if copy ~= nil then
		return copy
	end
	
	copy = {}
	already_seen[orig] = copy -- memoize before any recursion, to avoid infinite loops
	
	for orig_key, orig_value in pairs(orig) do
		copy[_deepCopy(orig_key, includeMetatable, already_seen)] = _deepCopy(orig_value, includeMetatable, already_seen)
	end
	
	if includeMetatable then
		local mt = getmetatable(orig)
		if mt ~= nil then
			setmetatable(copy, _deepCopy(mt, true, already_seen))
		end
	end
	
	return copy
end

function p.deepCopy(orig, noMetatable, already_seen)
	checkType("deepCopy", 3, already_seen, "table", true)
	return _deepCopy(orig, not noMetatable, already_seen or {})
end

------------------------------------------------------------------------------------
-- sparseConcat
--
-- Concatenates all values in the table that are indexed by a number, in order.
-- sparseConcat{a, nil, c, d}  =>  "acd"
-- sparseConcat{nil, b, c, d}  =>  "bcd"
------------------------------------------------------------------------------------
function p.sparseConcat(t, sep, i, j)
	local arr = {}

	local arr_i = 0
	for _, v in p.sparseIpairs(t) do
		arr_i = arr_i + 1
		arr[arr_i] = v
	end

	return table.concat(arr, sep, i, j)
end

------------------------------------------------------------------------------------
-- length
--
-- Finds the length of an array, or of a quasi-array with keys such as "data1",
-- "data2", etc., using an exponential search algorithm. It is similar to the
-- operator #, but may return a different value when there are gaps in the array
-- portion of the table. Intended to be used on data loaded with mw.loadData. For
-- other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of  the number
-- of unnamed template parameters, so use this function for frame.args.
------------------------------------------------------------------------------------
function p.length(t, prefix)
	-- requiring module inline so that [[Module:Exponential search]] which is
	-- only needed by this one function doesn't get millions of transclusions
	local expSearch = require("Module:Exponential search")
	checkType('length', 1, t, 'table')
	checkType('length', 2, prefix, 'string', true)
	return expSearch(function (i)
		local key
		if prefix then
			key = prefix .. tostring(i)
		else
			key = i
		end
		return t[key] ~= nil
	end) or 0
end

------------------------------------------------------------------------------------
-- inArray
--
-- Returns true if searchElement is a member of the array, and false otherwise.
-- Equivalent to JavaScript array.includes(searchElement) or
-- array.includes(searchElement, fromIndex), except fromIndex is 1 indexed
------------------------------------------------------------------------------------
function p.inArray(array, searchElement, fromIndex)
	checkType("inArray", 1, array, "table")
	-- if searchElement is nil, error?

	fromIndex = tonumber(fromIndex)
	if fromIndex then
		if (fromIndex < 0) then
			fromIndex = #array + fromIndex + 1
		end
		if fromIndex < 1 then fromIndex = 1 end
		for _, v in ipairs({unpack(array, fromIndex)}) do
			if v == searchElement then
				return true
			end
		end
	else
		for _, v in pairs(array) do
			if v == searchElement then
				return true
			end
		end
	end
	return false
end

------------------------------------------------------------------------------------
-- merge
--
-- Given the arrays, returns an array containing the elements of each input array
-- in sequence.
------------------------------------------------------------------------------------
function p.merge(...)
	local arrays = {...}
	local ret = {}
	for i, arr in ipairs(arrays) do
		checkType('merge', i, arr, 'table')
		for _, v in ipairs(arr) do
			ret[#ret + 1] = v
		end
	end
	return ret
end

------------------------------------------------------------------------------------
-- extend
--
-- Extends the first array in place by appending all elements from the second
-- array.
------------------------------------------------------------------------------------
function p.extend(arr1, arr2)
	checkType('extend', 1, arr1, 'table')
	checkType('extend', 2, arr2, 'table')

	for _, v in ipairs(arr2) do
		arr1[#arr1 + 1] = v
	end
end

return p
祛斑喝什么花茶最有效 三头六臂开过什么生肖 热疙瘩用什么药膏 乳液是什么 今夕何夕什么意思
有且仅有什么意思 甲状腺有什么作用 卤肉是什么肉 氟康唑治什么妇科炎症 什么肠小道成语
梦见剃光头是什么预兆 脚为什么脱皮 鹦鹉喜欢吃什么东西 小便发黄什么原因 面子是什么意思
孺子可教什么意思 尿精是什么原因造成的 疝气是什么病怎样治疗 扭转乾坤什么意思 k值是什么意思
猫爪草有什么功效hcv8jop1ns2r.cn 妯娌是什么意思hcv8jop5ns6r.cn 脸上长粉刺是什么原因96micro.com 科颜氏属于什么档次hebeidezhi.com 榴莲吃多了有什么危害hcv9jop1ns9r.cn
肚子痛吃什么药好hcv8jop8ns0r.cn 为什么放生泥鳅果报大hcv8jop8ns0r.cn 什么花一年四季都开bysq.com 多愁善感是什么意思hcv8jop5ns1r.cn 清凉的什么hcv7jop4ns7r.cn
ga是什么激素hcv9jop2ns5r.cn 项羽是什么生肖hcv7jop6ns5r.cn 生死有命富贵在天什么意思hcv8jop2ns1r.cn 朱雀玄武是什么意思hcv8jop9ns4r.cn 虚汗是什么症状hcv8jop3ns7r.cn
神经疼是什么原因hcv8jop0ns2r.cn 何以笙箫默什么意思hcv8jop7ns9r.cn 什么是湿气重hcv7jop9ns5r.cn 燃面为什么叫燃面hcv8jop4ns2r.cn 高血糖适合吃什么主食hcv7jop6ns3r.cn
百度