模块:Var-array/main
可在模块:Var-array/main/doc创建此模块的帮助文档
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