Function 动态表或数组

Function 动态表或数组,function,lua,lua-table,Function,Lua,Lua Table,我有一个函数,用来动态更改3D数组或表的大小,但它不断中断,说它返回值nil,因为它超出了范围。下面是它的代码: function resize() temp = { } for h=1, height do table.insert( temp , { } ) for y=1, length do table.insert ( temp[h], { } ) for x=1, width

我有一个函数,用来动态更改3D数组或表的大小,但它不断中断,说它返回值nil,因为它超出了范围。下面是它的代码:

function resize()       
    temp = { }
    for h=1, height do
        table.insert( temp , { } )
        for y=1, length do
            table.insert ( temp[h], { } )
            for x=1, width do
                num = 16                
                if #blocks <= height then
                    if #blocks[h] <= length then
                        if #blocks[h][y] <= width then
                            num = blocks[h][y][x]
                        end
                    end
                end         
                table.insert( temp[h][y] , num )
            end
        end
    end 
    blocks = temp
end
function resize()
温度={}
对于h=1,高度为
表.insert(临时,{})
对于y=1,长度do
table.insert(temp[h],{})
对于x=1,宽度为
num=16

if#blocks我认为错误在于if语句。您应该根据h、y和x来确定块的大小,而不是高度、长度和宽度


请注意,如果可以用temp[h]={}替换table.insert,请不要使用它。它更快。另外,试着用本地人来做临时存储。

我不确定这是否是最好的方法,但确实有效

function resize()       
temp = { } -- temp table

-- inserting all the height levels
for h=1, height do table.insert( temp , { } ) end

-- inserting all the lengths
for h=1, height do
    for l=1, length do table.insert( temp[h], { } ) end
end

-- inserting all the width and defaulting them to 0
for h=1, height do
    for l=1, length do
        for w=1, width do table.insert( temp[h][l] , 0 ) end
    end
end

-- if the canvas size is increasing
if #blocks <= height then
    if #blocks[1] <= length then
        if #blocks[1][1] <= width then
            for h=1, #blocks do
                for l=1, #blocks[1] do
                    for w=1, #blocks[1][1] do
                        -- fill in data from blocks
                        temp[h][l][w] = blocks[h][l][w]
                    end
                end
            end
        end
    end
end

--if the canvas size is decreasing
if #blocks >= height then
    if #blocks[1] >= length then
        if #blocks[1][1] >= width then
            for h=1, #temp do
                for l=1, #temp[1] do
                    for w=1, #temp[1][1] do
                        -- fill in data from blocks but not the last value
                        temp[h][l][w] = blocks[h][l][w]
                    end
                end
            end
        end
    end
end

-- overwrite blocks with the new dimensions
blocks = temp
function resize()
temp={}--temp表
--插入所有高度级别
对于h=1,高度do table.insert(temp,{})end
--插入所有长度
对于h=1,高度为
对于l=1,长度为do table.insert(temp[h],{})end
结束
--插入所有宽度并将其默认为0
对于h=1,高度为
对于l=1,长度do
对于w=1,宽度为表。插入(温度[h][l],0)结束
结束
结束
--如果画布大小正在增加
如果#块=宽度,则
当h=1时,#温度do
对于l=1,#temp[1]do
当w=1时,#temp[1][1]do
--填写数据块中的数据,但不填写最后一个值
温度[h][l][w]=块[h][l][w]
结束
结束
结束
结束
结束
结束
--用新标注覆盖块
块=温度
您的具体错误(可能) 不针对nil值进行测试。根据定义,任何未初始化的表(=本例中的数组)成员都是
nil
。将
nil
与数字进行比较将产生错误:

lua: attempt to compare nil with number
然而,由于您似乎无法提供实际的错误消息,这只是一个猜测。不要误会我这些都是代码中的错误,但我可能忽略了其他一些错误。不管怎样,这里有一些注释和代码来告诉您发生了什么

if #blocks <= height then              -- say #blocks is 3, height is 4
    if #blocks[h] <= length then       -- E: in iteration 4 blocks[h] is nil
        if #blocks[h][y] <= width then -- E: in it. 3,4 blocks[h][y] is nil
            num = blocks[h][y][x]
        end
    end
end
然后,您只需执行以下操作即可制作一个调整大小的副本:

function resizeMdArray(array, X, Y, Z)
    local r = newMdArray(X, Y, Z);
    for x=1, X do
        for y=1, Y do
            for z=1, Z do
                r(x, y, z, array(x, y, z) or 16);
            end
        end
    end
    return r;
end
一个很好的好处是,由于此数据结构将3D数组展平为1D数组,如果您只想复制数据,只需将其作为表访问并复制每个元素即可:

for i=1, X*Y*Z do
    new[i] = old[i]
end

当然,你也可以在后台使用一个“真实”(隐藏)的三维数组来保存算术计算,但是你必须一直测试空值,以防止出现零错误。

请添加准确的错误消息并在代码中标记行。我可能遗漏了什么,但是为什么不直接从现有的表中添加或删除元素,而不是移动所有的数据呢?谢谢,我不知道你也可以这样说,temp[h]={},高度、长度、宽度实际上是h、y、x,我只是这样命名它们,以便于阅读。@user1990152-不,它们不一样。h,对于从1增加到高度、宽度和长度的变量,y和x是局部变量。通过比较
#块
与高度,我想你总是会将其与新高度进行比较。因此,当您扩展阵列时,您永远不会得到pat the
if
s.Mmm,这比我预期的要深入一点。。。我知道你在用它做什么,它是有效的,但我得到了一个修复,这是一个简单得多。谢谢哦,这是很久以前的事了。。。但我想我没有看到你的答案。尽管我认为这个解决方案使用起来要简单得多,因为无论何时您想要访问数据,都不必“手动”测试
nil
。但这当然是你的决定。
function resizeMdArray(array, X, Y, Z)
    local r = newMdArray(X, Y, Z);
    for x=1, X do
        for y=1, Y do
            for z=1, Z do
                r(x, y, z, array(x, y, z) or 16);
            end
        end
    end
    return r;
end
for i=1, X*Y*Z do
    new[i] = old[i]
end