在 lua 中创建单个迭代解包函数的更好方法
Better way to create a single iterative unpack function in lua
Lua 解包函数只适用于简单的 table,所以我想写一个可以解包复杂的 table 的函数。它工作正常,但我正在寻找更好的方法来编写这样的函数。代码如下:
c = {1,2,{3,4},{{5,6},{7,8}}}
vt = {}
function convertToSimpleTable(t,vacantTable)
if type(t)=="table" then
for _,val in ipairs(t) do
if type(val)=="table" then
convertToSimpleTable(val,vacantTable)
else
table.insert(vacantTable,val)
end
end
return vacantTable
else
return {t}
end
end
print(unpack(convertToSimpleTable(c,vt)))
输出:
1 2 3 4 5 6 7 8
为了让这个函数工作,我需要提供一个空的 table 因为如果我在函数内部初始化一个 table 它会被重新初始化,因为函数是迭代的,因此会给出错误的结果
只需添加:
vacantTable=vacantTable or {}
到函数的开头。或者创建第二个函数并从基本包装器调用这个函数:
function convertToSimpleTable(t)
return convertToSimpleTable_impl(t, {})
end
另一种可能性:
c = {1,2,{3,4},{{5,6},{7,8}}}
function convertToSimpleTable(t)
local ans = {}
for _,t in ipairs(t) do
if type(t) == 'table' then
for _,t in ipairs(convertToSimpleTable(t)) do
ans[#ans+1] = t
end
else
ans[#ans+1] = t
end
end
return ans
end
print(unpack(convertToSimpleTable(c)))
特别感谢Dan200 for writing this fantastic code。
local function serializeImpl( t, tTracking, sIndent )
local sType = type(t)
if sType == "table" then
if tTracking[t] ~= nil then
error( "Cannot serialize table with recursive entries", 0 )
end
tTracking[t] = true
if next(t) == nil then
-- Empty tables are simple
return "{}"
else
-- Other tables take more work
local sResult = "{\n"
local sSubIndent = sIndent .. " "
local tSeen = {}
for k,v in ipairs(t) do
tSeen[k] = true
sResult = sResult .. sSubIndent .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
for k,v in pairs(t) do
if not tSeen[k] then
local sEntry
if type(k) == "string" and not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
sEntry = k .. " = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
else
sEntry = "[ " .. serializeImpl( k, tTracking, sSubIndent ) .. " ] = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
sResult = sResult .. sSubIndent .. sEntry
end
end
sResult = sResult .. sIndent .. "}"
return sResult
end
elseif sType == "string" then
return string.format( "%q", t )
elseif sType == "number" or sType == "boolean" or sType == "nil" then
return tostring(t)
else
error( "Cannot serialize type "..sType, 0 )
end
end
function serialize( t )
local tTracking = {}
return serializeImpl( t, tTracking, "" )
end
PS:最初是为名为 Computer Craft 的 Minecraft mod 制作的,因此某些功能可能无法使用。
Lua 解包函数只适用于简单的 table,所以我想写一个可以解包复杂的 table 的函数。它工作正常,但我正在寻找更好的方法来编写这样的函数。代码如下:
c = {1,2,{3,4},{{5,6},{7,8}}}
vt = {}
function convertToSimpleTable(t,vacantTable)
if type(t)=="table" then
for _,val in ipairs(t) do
if type(val)=="table" then
convertToSimpleTable(val,vacantTable)
else
table.insert(vacantTable,val)
end
end
return vacantTable
else
return {t}
end
end
print(unpack(convertToSimpleTable(c,vt)))
输出:
1 2 3 4 5 6 7 8
为了让这个函数工作,我需要提供一个空的 table 因为如果我在函数内部初始化一个 table 它会被重新初始化,因为函数是迭代的,因此会给出错误的结果
只需添加:
vacantTable=vacantTable or {}
到函数的开头。或者创建第二个函数并从基本包装器调用这个函数:
function convertToSimpleTable(t)
return convertToSimpleTable_impl(t, {})
end
另一种可能性:
c = {1,2,{3,4},{{5,6},{7,8}}}
function convertToSimpleTable(t)
local ans = {}
for _,t in ipairs(t) do
if type(t) == 'table' then
for _,t in ipairs(convertToSimpleTable(t)) do
ans[#ans+1] = t
end
else
ans[#ans+1] = t
end
end
return ans
end
print(unpack(convertToSimpleTable(c)))
特别感谢Dan200 for writing this fantastic code。
local function serializeImpl( t, tTracking, sIndent )
local sType = type(t)
if sType == "table" then
if tTracking[t] ~= nil then
error( "Cannot serialize table with recursive entries", 0 )
end
tTracking[t] = true
if next(t) == nil then
-- Empty tables are simple
return "{}"
else
-- Other tables take more work
local sResult = "{\n"
local sSubIndent = sIndent .. " "
local tSeen = {}
for k,v in ipairs(t) do
tSeen[k] = true
sResult = sResult .. sSubIndent .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
for k,v in pairs(t) do
if not tSeen[k] then
local sEntry
if type(k) == "string" and not g_tLuaKeywords[k] and string.match( k, "^[%a_][%a%d_]*$" ) then
sEntry = k .. " = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
else
sEntry = "[ " .. serializeImpl( k, tTracking, sSubIndent ) .. " ] = " .. serializeImpl( v, tTracking, sSubIndent ) .. ",\n"
end
sResult = sResult .. sSubIndent .. sEntry
end
end
sResult = sResult .. sIndent .. "}"
return sResult
end
elseif sType == "string" then
return string.format( "%q", t )
elseif sType == "number" or sType == "boolean" or sType == "nil" then
return tostring(t)
else
error( "Cannot serialize type "..sType, 0 )
end
end
function serialize( t )
local tTracking = {}
return serializeImpl( t, tTracking, "" )
end
PS:最初是为名为 Computer Craft 的 Minecraft mod 制作的,因此某些功能可能无法使用。