在 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 制作的,因此某些功能可能无法使用。