保存带有循环的表

简介: 保存带有循环的表

由于表构造器不能创建带有循环的或共享字表的表,所以如果要处理表示通用拓扑结构(例如带有循环或共享字表)的表,就需要采用不同的方法。我们需要引入名称来表示循环。因此,下面的函数把值外加其名称一起作为参数。另外,还必须用一个额外的表来存储以保存表的名称,以便在发现循环时对其进行复用。这个额外的表使用此前已被保存的表作为,以表的名称作为

function basicSerialize(o)
  -- 假设'o'是一个数字或字符串
  return string.format("%q", o)
end
function save(name, value, saved)
  saved = saved or {}   -- 初始值
  io.write(name, " = ")
  if type(value) == "number" or type(value) == "string" then
    io.write(basicSerialize(value), "\n")
  elseif type(value) == "table" then
    if saved[value] then              -- 值是否已被保存?
      io.write(saved[value], "\n")    -- 使用之前的名称
    else
      saved[value] = name
      io.write("{}\n")
      for k, v in pairs(value) do
        k = basicSerialize(k)
        local fname = string.format("%s[%s]", name, k)
        save(fname, v, saved)
      end
    end
  else
    error("cannot save a " .. type(value))
  end
end


我们假设要序列化的表只使用字符串或数值作为键。函数 basicSerialize 用于对这些基本类型进行序列化并返回序列化后的结果,另一个函数 save 则完成具体的工作,其参数 saved 就是之前所说的用于存储已保存表的表。例如,假设要创建一个如下所示的表:

a = {x = 1, y = 2; {3, 4, 5}}
a[2] = a    -- 循环
a.z = a[1]  -- 共享字表


调用 save("a", a) 会将其保存为:

a = {}
a[1] = {}
a[1][1] = 3
a[1][2] = 4
a[1][3] = 5
a[2] = a
a["z"] = a[1]
a["y"] = 2
a["x"] = 1


取决于表的遍历情况,这些赋值语句的实际执行顺序可能会有所不同。不过尽管如此,上述算法能够保证任何新定义节点中所用到的节点都是已经被定义过的。


如果想保存具有共享部分的几个表,那么可以在调用函数 save 时使用相同的表 saved 函数。例如,假设有如下两个表:

a = {{"one", "two"}, 3}
b = {k = a[1]}


如果以独立的方式保存这些表,那么结果中不会有共同的部分。不过,如果调用 save 函数时使用同一个表 saved ,那么结果就会共享共同的部分:

local t = {}
save("a", a, t)
save("b", b, t)


输出:

a = {}
a[1] = {}
a[1][1] = "one"
a[1][2] = "two"
a[2] = 3
b = {}
b["k"] = a[1]


Lua 语言中,还有其他一些比较常见的方法。例如,我们可以在保存一个值时不指定全局名称而是通过一段代码来创建一个局部值并将其返回,也可以在可能的时候使用列表的语法等等。 Lua 语言给我们提供了构建这些机制的工具。

目录
相关文章
|
小程序 JavaScript
小程序简单循环列表数据渲染实例
小程序简单循环列表数据渲染实例
85 0
|
4月前
|
关系型数据库 MySQL 数据库
mysql,归零,无法自动排序,删除id,表单的数据没有从零开始出现怎样解决?删除数据仍然从删除的地方该怎样解决?表单的数据没有从2开始,而是从之前的删除的序号开始自增。
mysql,归零,无法自动排序,删除id,表单的数据没有从零开始出现怎样解决?删除数据仍然从删除的地方该怎样解决?表单的数据没有从2开始,而是从之前的删除的序号开始自增。
|
6月前
|
Java 大数据 数据处理
获取到数据循环写文件
这段代码是一个Java方法,用于分批处理数据。它定义了初始值和每批处理的数量,然后通过`PageInfo`对象获取数据。如果总数小于1,则直接返回空列表。否则,循环处理数据,防止环境中的多次空跳过,并在处理完一批数据后更新页码。代码中还提到,这个过程可以用于减少大数据操作带来的风险。此外,配有一张动图,可能表示数据处理的过程。
43 1
|
6月前
|
关系型数据库 MySQL 测试技术
当update修改数据与原数据相同时会再次执行吗
当update修改数据与原数据相同时会再次执行吗
50 1
Navicat保存下来的查询放在哪个位置
保存后的查询文件查找位置:
1058 0
Navicat保存下来的查询放在哪个位置
|
算法
保存不带循环的表
保存不带循环的表
86 0
for循环写入100条数据到文件中 1.获取文件对象 2.for循环 100次 3.每次都要想文件中写入内容
for循环写入100条数据到文件中 1.获取文件对象 2.for循环 100次 3.每次都要想文件中写入内容