保存带有循环的表

简介: 保存带有循环的表

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

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
小程序简单循环列表数据渲染实例
小程序简单循环列表数据渲染实例
106 0
|
9月前
|
存储 弹性计算 运维
从文件中删除重复的行
【4月更文挑战第29天】
60 1
|
9月前
|
Java 大数据 数据处理
获取到数据循环写文件
这段代码是一个Java方法,用于分批处理数据。它定义了初始值和每批处理的数量,然后通过`PageInfo`对象获取数据。如果总数小于1,则直接返回空列表。否则,循环处理数据,防止环境中的多次空跳过,并在处理完一批数据后更新页码。代码中还提到,这个过程可以用于减少大数据操作带来的风险。此外,配有一张动图,可能表示数据处理的过程。
59 1
|
9月前
|
关系型数据库 MySQL 测试技术
当update修改数据与原数据相同时会再次执行吗
当update修改数据与原数据相同时会再次执行吗
60 1
|
算法
保存不带循环的表
保存不带循环的表
99 0
|
索引
按顺序遍历表
按顺序遍历表
145 0
遍历表
遍历表
95 0
|
小程序 PHP
解决往数组添加数据,第二次会覆盖第一次的方案
解决往数组添加数据,第二次会覆盖第一次的方案
338 0
for循环写入100条数据到文件中 1.获取文件对象 2.for循环 100次 3.每次都要想文件中写入内容
for循环写入100条数据到文件中 1.获取文件对象 2.for循环 100次 3.每次都要想文件中写入内容
按顺序逐个同步地运行 Gulp 任务
按顺序逐个同步地运行 Gulp 任务 我们在使用gulp的时候,有时候需要按顺序同步的执行gulp任务 gulp-sequence 使用这个插件就可以了 下面是使用方法: var gulpSequence = require('gulp-sequence'); gulp.
1250 0