Module:Var-array/main
跳到导航
跳到搜索
- local module = {}
- local getArgs = require("Module:Arguments").getArgs
- local varArray = require("Module:var-array")
- local var = require("Module:var")
- local frame = mw.getCurrentFrame()
- local _count = {
- get = function(array)
- return var.get(array .. ".count")
- end
- }
- _count.plus = function(array)
- return tonumber(var.set(array .. ".count", _count.get(array) + 1))
- end
- _count.minus = function(array)
- return tonumber(var.set(array .. ".count", _count.get(array) - 1))
- end
- local prefix = "@array-innerArrayIdentifier:"
- function _ifArrayIndex(val)
- return (tostring(val or ''):find("^@array%-innerArrayIdentifier:.+"))
- end
- function _getArrayIndex(args, askValueIndex)
- local arrayIndex = prefix .. args[2]
- if arrayIndex ~= var.getPlain(arrayIndex) then
- error("变量组名无效", 0)
- end
- local argsCount = 0
- if askValueIndex then
- for i, v in ipairs(args) do
- argsCount = i
- end
- end
- for i, v in ipairs(args) do
- if i > 2 then
- if askValueIndex and i == argsCount then
- arrayIndex = arrayIndex .. v
- else
- if (v == "count") then
- v = ".count"
- end
- arrayIndex = var.getPlain(arrayIndex .. v)
- end
- end
- end
- return arrayIndex
- end
- function _new(args, isOmit)
- local id = args["id"] or args["name"]
- if id == nil then
- error("构造变量组时“name”或“id”不能为空", 0)
- end
- local name = prefix .. id
- var.set(name, name)
- -- 用ipairs遍历args在遇到空匿名参数时会中断
- local count = 0
- for i, v in pairs(args) do
- if tostring(i):find("^%d+$") then
- i = tonumber(i)
- if isOmit then
- var.set(name .. i, v)
- if i > count then
- count = i
- end
- elseif i > 1 then
- i = i - 1
- var.set(name .. i, v)
- if i > count then
- count = i
- end
- end
- end
- end
- var.set(name .. ".count", count)
- var.set("array.savedNameUseForArrayId", id)
- return id
- end
- function _id()
- local savedName = var.get("array.savedNameUseForArrayId") or math.random()
- local idCount = (var.get("array.idCount") or 0) + 1
- var.set("array.idCount", idCount)
- return prefix .. savedName .. "___" .. idCount .. "___"
- end
- function _in(args)
- local name = _id()
- local count = 0
- var.set(name, name)
- for i, v in pairs(args) do
- if tostring(i):find("^%d+$") then
- i = tonumber(i)
- if i > 1 then
- i = i - 1
- var.set(name .. i, v)
- if i > count then
- count = i
- end
- end
- end
- end
- var.set(name .. ".count", count)
- return name
- end
- function _get(args)
- local result = _getArrayIndex(args)
- if _ifArrayIndex(result) then
- error("不能获取变量组的索引值", 0)
- end
- return result
- end
- function _set(args)
- local index = _getArrayIndex(args, true)
- if _ifArrayIndex(var.get(index)) then
- error("不能对变量组索引进行赋值", 0)
- end
- return var.set(index, args["val"])
- end
- function _push(val, array, count)
- var.set(array .. (count + 1), val)
- return _count.plus(array)
- end
- function _pop(array, count)
- if count == 0 then
- return
- end
- _count.minus(array)
- return var.remove(array .. count)
- end
- function _unshift(val, array, count)
- for i = count, 1, -1 do
- local val = var.getPlain(array .. i)
- var.set(array .. (i + 1), val)
- end
- var.set(array .. "1", val)
- return _count.plus(array)
- end
- function _shift(array, count)
- if count == 0 then
- return
- end
- local deletedVal = var.getPlain(array .. 1)
- for i = 2, count do
- local val = var.getPlain(array .. i)
- var.set(array .. (i - 1), val)
- end
- var.set(array..count, '')
- _count.minus(array)
- return deletedVal
- end
- function _splice(array, count, startIndex, howmany, args)
- local vals = {}
- for i, v in pairs(args) do
- if tostring(i):find("^%d+$") then
- i = tonumber(i)
- if i > 1 then
- vals[#vals + 1] = v
- end
- end
- end
- if howmany == #vals then
- for i=1, howmany do
- var.set(array..(startIndex + i - 1), vals[i])
- end
- return count
- else
- local fragment = {}
- for i=startIndex + howmany, count do
- fragment[#fragment + 1] = var.remove(array..i)
- end
- for i=1, #vals do
- var.set(array..(startIndex + i - 1), vals[i])
- end
- -- 删除操作起始点和尾部保存起始点之间的成员
- local d_start = startIndex + #vals
- local d_end = count - #fragment
- local d_count = d_end - d_start + 2
- if d_count > #vals then
- for i=d_start, d_end do
- var.set(i, '')
- end
- end
- count = startIndex - 1 + #vals
- for i=1, #fragment do
- var.set(array..(count + i), fragment[i])
- end
- return var.set(array..'.count', count + #fragment)
- end
- end
- function module.main(frame)
- local args = getArgs(frame)
- function ifReturn(val)
- if args["r"] == "true" then
- return val
- end
- return ""
- end
- function getArray()
- local array = _getArrayIndex(args)
- if array == "" then
- error("变量组成员下标(序号)定位有误", 0)
- end
- local count = _count.get(array)
- return array, count
- end
- local switch = {
- new = function()
- return ifReturn(_new(args))
- end,
- ["in"] = function()
- return _in(args)
- end,
- get = function()
- return _get(args)
- end,
- set = function()
- return ifReturn(_set(args))
- end,
- push = function()
- local array, count = getArray()
- return ifReturn(_push(args["val"], array, count))
- end,
- pop = function()
- local array, count = getArray()
- return ifReturn(_pop(array, count))
- end,
- unshift = function()
- local array, count = getArray()
- return ifReturn(_unshift(args["val"], array, count))
- end,
- shift = function()
- local array, count = getArray()
- return ifReturn(_shift(array, count))
- end,
- getIndex = function()
- return _getArrayIndex(args)
- end,
- ifIndex = function()
- if _ifArrayIndex(args[2]) then
- return 1
- end
- end,
- splice = function()
- local array = args['index']
- local count = var.get(array..'.count')
- local start = tonumber(args['start'] or 1)
- local howmany = tonumber(args['howmany'] or 1)
- if start > count then error('start参数(操作起点)不能大于变量组的长度', 0) end
- if _ifArrayIndex(array)
- then return ifReturn(_splice(array, count, start, howmany, args))
- else error('变量组索引无效', 0)
- end
- end,
- print = function()
- local content = mw.dumpObject(varArray.get((getArray()):gsub("^@array%-innerArrayIdentifier:", "")))
- return frame:extensionTag("pre", content)
- end
- }
- local hasTargetMethod = false
- for k, v in pairs(switch) do
- if k == args[1] then
- hasTargetMethod = true
- break
- end
- end
- if hasTargetMethod then
- return switch[args[1]]()
- else
- return ifReturn(_new(args, true))
- end
- end
- return module