Lua中创建单一迭代解压函数的更好方法

Lua的unpack函数仅适用于简单的表,因此我想编写一个可以解压复杂表的函数。它可以正常工作,但是我正在寻找更好的编写此类函数的方法。代码如下:

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

要使该函数工作,我需要提供一个空表,因为如果在函数内部初始化表,它会在函数迭代时重新初始化,从而产生错误的结果。

点赞
用户734069
用户734069

只需在函数开始添加:

vacantTable=vacantTable or {}

或者创建一个第二个函数,从基本包装器中调用此函数:

function convertToSimpleTable(t)
  return convertToSimpleTable_impl(t, {})
end
2016-06-09 16:20:20
用户3735873
用户3735873

另外一种可能性:

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)))
2016-06-10 06:30:41
用户5675171
用户5675171

特别感谢Dan200编写了这个神奇代码

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
            --空表很简单
            return "{}"
        else
            --其他表需要更多工作
            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:初始版本用于Minecraft mod的Computer Craft,因此某些功能可能无法正常工作。

2016-06-14 01:01:01