Lua:如何循环遍历非固定域 简介: 在Lua中,循环遍历一个非固定域(即键名不是数字或者在数组范围内的字符串)是一项重要的任务。本文将介绍如何使用Lua循环遍历一个非固定域。 方法: 1. 使用pairs函数 使用pairs函数可以在遍历非固定域时保留键名以及对应的值。具体用法如下: ```lua t = { key1 = "value1", key2 = "value2", key3 = "value3", } for k,v in pairs(t) do print(k, v) end ``` 以上例子会打印出: ``` key1 value1 key2 value2 key3 value3 ``` 2. 使用ipairs函数 使用ipairs函数只能遍历连续数字下标的数组。如果键名不是数字或不是连续数字,则ipairs函数会停止遍历。因此,使用pairs函数遍历非固定域更为常用。 ```lua t = { "value1", "value2", "value3", } for i,v in ipairs(t) do print(i, v) end ``` 以上例子会打印出: ``` 1 value1 2 value2 3 value3 ``` 总结: 使用pairs函数可以遍历非固定域,而ipairs函数只适用于遍历连续数字下标的数组。在实际应用中,建议使用pairs函数。

通常我会使用 Lua 来生成一个数据文件,其中包含已知表达式的曲线的坐标。然后,我会使用其他程序绘制曲线。

不过,我也想绘制通过对第一个曲线的表达式中的参数进行变化而获得的曲线。

举个例子,我想绘制以 y=x^1y=x^1.5y=x^2 等形式的幂,其中我所说的参数是指数(即 1、1.5、2 等)。

下面是我的常规工作流程示例(我希望代码比我解释得更好):

-- test.lua
function POWER(x, y)
   return x^y
end

local xmin = 0 -- x: the abscissa
local xmax = 10
local xstep = 0.1

local ymin = 1 -- y: the parameter
local ymax = 2
local ystep = 0.5

local A = {}
local ix = 1 -- dummy variable to index A as an array
for I = xmin, xmax, xstep do
   A[ix] = {}
   A[ix].x = I
   A[ix].y = {}
   for J = ymin, ymax, ystep do
      table.insert(A[ix].y, POWER(I, J))
   end
   ix = ix + 1
end

local Out = io.stdout
--local Out = io.open("powerOUT.dat", "w")
Out:write("  x        x^1      x^1.5        x^2\n") -- from here on out I have to adjust things manually if I change ymin, ymax or ystep
for _, v in ipairs(A) do
   Out:write(string.format("%5.2f %10f %10f %10f\n",
               v.x, v.y[1], v.y[2], v.y[3]))
end

这是我得到的摘录:

    x        x^1      x^1.5        x^2
 0.00   0.000000   0.000000   0.000000
 0.10   0.100000   0.031623   0.010000
 0.20   0.200000   0.089443   0.040000
 0.30   0.300000   0.164317   0.090000
 ...

xmin...ymin... 的问题在于,我想使过程“自动化”(即,我想更改其中某些变量的值,并使数据文件相应更改)。到目前为止,对于横坐标 x,该过程是自动的(我可以更改域和采样数),但对于参数 y 则不然(请参阅我发布的代码)。

所以问题是:在更改 y 变量的值时,如何向我的数据文件添加列,而不需要手动调整输出?

在这个例子中,这个问题转化为:如何将 ymaxystep 更改为 ymax=5ystep=0.25,而无需手动更改脚本末尾的 :write 语句?

请注意,数据文件的第一行应根据新值进行调整。

这是我想得到的:

    x     x^1.00     x^1.25     x^1.50     x^1.75     x^2.00     x^2.25     x^2.50     x^2.75     x^3.00     x^3.25     x^3.50  ...
 0.00   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000   0.000000 ...
 0.10   0.100000   0.056234   0.031623   0.017783   0.010000   0.005623   0.003162   0.001778   0.001000   0.000562   0.000316 ...
 0.20   0.200000   0.133748   0.089443   0.059814   0.040000   0.026750   0.017889   0.011963   0.008000   0.005350   0.003578 ...
 0.30   0.300000   0.222025   0.164317   0.121608   0.090000   0.066607   0.049295   0.036482   0.027000   0.019982   0.014789 ...
 ...

顺便说一句,我承认我的流程可能不是最优的,因此任何建议都受欢迎。我的工作流背后的一般思想是将所有数据存储在一个数组中,因为可以使用 ipairs() 以“正确的顺序”打印结果。

点赞
用户2726734
用户2726734

基本上,由于列的数量可能会更改,我们可以使用循环来遍历所有列,逐列而不是逐行打印。只需用下面的代码替换输出部分,并将ymin,ymax和ystep更改为您想要的值。边打印边走也是另一个选择。

Out:write("pos    ")
for y = ymin,ymax,ystep do
      Out:write(string.format("y=%-5.2f     ", y))
end
Out:write("\n")
for _,v in ipairs(A) do
   Out:write(string.format("%5.2f ", v.x))
   for _,y in ipairs(v.y) do
      Out:write(string.format("%10f ", y))
   end
   Out:write("\n")
end
2015-01-05 19:05:34