lua中实现table的打印

刚学lua不久,导师布置的一个作业,实现一个能处理table的print

--[[
  evn:Lua 5.1
]]
function prettystring(...)
    for key, value in pairs({...}) do
        prettyOneString(value)
    end
end

function prettyOneString(data,onlyTable,tab) --data处理的数据,onlyTable记录表,tab为tab数量
  printTab = function (n)
      for i=0,n do
          io.write("    ")  --tab
      end
  end
    if onlyTable == nil then
      onlyTable = {}
    end
    if(tab == nil) then
      tab = 0
    end
    if type(data) ~= 'table' then --非table情况
        if type(data) == 'string' then
          io.write(data)
        else
          io.write(tostring(data))
        end
        if tab ~= 0 then  --处理table成员末尾的逗号
          io.write(",")
        end
        io.write("\n")
    else  --处理table
        io.write("{\n")
        if next(data) ~= nil and not findTableValue(onlyTable,data) then
          table.insert(onlyTable,data)  --坑:是table.insert(),不是table成员.insert()
          for index, value in pairs(data) do
              if type(index) == 'string' then  
                printTab(tab)
                io.write("[\""..tostring(index).."\"] " .. "= ")
              else
                printTab(tab)
                io.write("["..tostring(index).."] " .. "= ")
              end
              prettyOneString(value,onlyTable,tab+1)
          end
        end
        printTab(tab-1)  --格式对齐
        io.write("},\n")
    end
end

function findTableValue(table,findValue)  --寻找value是否在table中
  if next(table) == nil then
      return false
  end
  for key, value in pairs(table) do
      if value == findValue then
          return true
      end
  return false
  end
end


但是还是有几个地方有问题。

  1. 没用使用local修饰局部变量
  2. 字符串…连接消耗性能大,最好用table.concat()
  3. 寻找循环引用表可以使用 {[table] = “@/位置”} 的方式,一方面优化了查询时间,另一方面可以之间找到表第一次出现的位置
  4. paris无法处理nil,必须使用select("#",…)
  5. 给table添加手动计数器,取代#table,但是可读性个人觉得会差一点

修改后为

local function prettystring(...)
    local tinsert = table.insert
    local uniqueTable = {}
    local function prettyOneString(data,tab,path)
        tab = tab or 0
        path = path or "@/"
        local retTable  = {}    --存储最后的结果

        if type(data) ~= 'table'  then   --处理非table
            tinsert(retTable ,tostring(data))
            if tab ~= 0 then
                tinsert(retTable,",")
            end
        else    --处理table
            if uniqueTable[tostring(data)] == nil then
                tinsert(retTable,"{\n")
            end
            if next(data) ~= nil and uniqueTable[tostring(data)] == nil then
                uniqueTable[tostring(data)] = path
                for key, value in pairs(data) do
                    tinsert(retTable,string.rep("\t",tab))
                    if type(key)  == 'string' then
                        local tmpString = string.format('["%s"] = ',tostring(key))    --string.format可读性会比较好点,性能略微损失
                        tinsert(retTable,tmpString)
                    else
                        local tmpString = string.format("[%s] = ",tostring(key))
                        tinsert(retTable,tmpString)
                    end
                    tinsert(retTable,prettyOneString(value,tab+1,path..tostring(key)..'/' ))
                    tinsert(retTable,"\n")
                end
                local tmpString = string.format("%s},",string.rep("\t",tab))
                tinsert(retTable,tmpString)
            else
                local tmpString = string.format("%s",uniqueTable[tostring(data)])
                tinsert(retTable,tmpString)
            end
        end
        return table.concat(retTable)
    end
    --start
    local argv = table.pack(...)
    for i=1,argv.n do --遍历参数
        local argcType = type(argv[i])
        if argcType == 'table' and i ~= 1 then
            io.write("\n")
        end
        io.write(prettyOneString(argv[i]))
        if argcType ~= 'table' and i ~= argv.n then
            io.write("\t")  --模拟print行为
        end
    end
    io.write("\n")
end

return prettystring
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值