# Assigning value to a 3d array making all previous values in 3d array nil

Whenever I try to set a value in my 3d array to a value in another 3d array it sets all previously set values in the array to nil.
Code:

``````local function cullNoise(map)
local culledMap = {}

for x, a in ipairs(map) do
if culledMap[x] == nil then culledMap[x] = {} end

for y, b in ipairs(a) do
if culledMap[x][y] == nil then culledMap[x][y] = {} end

for z, c in ipairs(b) do
if checkNeighbors(x, y, z, map) == false then
print(map[x][y][z]) --print the value from the array I want the value from
culledMap[x][y][z] = map[x][y][z] --Setting the value of the new array to the value from the old array (Problem line)
print(culledMap[x][y][z]) --print the new value that was set
if z - 1 > 0 then print(culledMap[x][y][z-1]) end --print the value set before it
end
end
end
end

return culledMap
end
``````

This is what the output shows: (cM = culledMap) (z-1 is the previous value set)

If it was confusing, my code sets culledMap[x][y][z] (which looks like
{ (x) { (y) { (z is index of `valueX`) `value1`, `value2`, â€¦ }, â€¦ }, â€¦ }, ) to another array that is set up in the same way, but the previous value apparently gets overridden and set to `nil` (`value1` is set to a value properly, but when `value2` is set `value1` becomes `nil`, along with all previous values)

Thank you!

You probably arenâ€™t overwriting it, you are accessing that location before it is created.

1 Like

I donâ€™t have a solution but I think it could be helpful to add one more print in the if statement and post the new output.

``````if checkNeighbors(x, y, z, map) == false then
print(string.format("x, y, z: %i, %i, %i", x, y, z))
print(map[x][y][z]) --print the value from the array I want the value from
culledMap[x][y][z] = map[x][y][z] --Setting the value of the new array to the value from the old array (Problem line)
print(culledMap[x][y][z]) --print the new value that was set
if z - 1 > 0 then print(culledMap[x][y][z-1]) end --print the value set before it
end
``````

What I think could be the problem is that `checkneighbors()` has returned true for the earlier z indices. However, from the output in the original post, I canâ€™t tell whether this is the case.

1 Like

I think I found the problem.
For some reason, when `culledMap` is called outside of the for loops it is blank (as in there are no values in the last arrays), but when it is inside the loops it returns fine (after improving the code at least)

Do you have any idea why it is doing this? (Thank you for the output suggestion btw)

In the first screenshot, you are showing the arrays at the second x index, but in the second screenshot, you are showing the arrays at the first x index.

Could you show the printed arrays at the first x index both inside and outside the loop and the printed arrays at the second x index both inside and outside the loop. For the arrays at the second x index inside the loop, show a print thatâ€™s from an iteration in which x is greater than 2.

If the arrays at the first x index after the loop are empty, Iâ€™m pretty sure they are also empty inside the loop.

Also, I still think it would be useful to show a sequence of the prints in my earlier reply (your original prints and the one I added). Those prints could actually show whether previously set values were set to nil or whether values for the previous indices were never even set to a non-nil value.

1 Like

For the second screenshot the 1st x index is the same as all the rest and the first screenshot has a random assortment of values for all x indexes. What I was trying to point out was how the array printed inside the for loop was different from when it was printed outside the loop, despite using the same variable. (also what I mean by â€ścompletely empty arrayâ€ť in the code screenshot is that the values that should be in the z array arent there, but it is still structured as a 3d array, sorry for any confusion)

If, after the loop, the array is actually missing values that it had during the loop, the only reason I can think of is that `checkNeighbors()` somehow causes that. Could you show the `checkneighbors()` function?

Edit: I realized that since it has no reference to `culledMap`, it canâ€™t modify it. However, I still think itâ€™s the reason for earlier z indices having nil as their value in culledMap.

1 Like

Here is the `checkNeighbors()` code:

``````local function checkNeighbors(x, y, z, map)
for xx = -1, 1, 1 do
for yy = -1, 1, 1 do
for zz = -1, 1, 1 do
if xx == 0 and yy == 0 and zz == 0 then
continue
elseif x == 1 or y == 1 or z == 1 or x == MAPLEN_X or y == MAPLEN_Y or z == MAPLEN_Z then
continue
elseif math.abs(xx) + math.abs(yy) + math.abs(zz) > 1 then
continue
elseif not map[x][y][z] then
continue
elseif not map[x + xx][y + yy][z + zz] then
return false
end
end
end
end
wait()
return true
end
``````

(MAPLEN_X, Y, and Z all have the same value of 30)

The only solution I can think of right now is, in the for loops in cullNoise, to check if `x` is equal to the length of `map`, if `y` is equal to the length of `a`, and if `z` is equal to the length of `b`, then use return the map from inside the for loops.

I have no idea what could cause values to be erased from `culledMap`. But, in regards to the problem in the original post (values of earlier z indices nil), are you sure that the values at the earlier z indices are not nil or false and that they have a nil or false neighbor value (in which case checkNeighbors() returns false and the if statement condition in cullNoise is satisfied)?

Also, you could write checkNeighbors differently. I think the code below will work the exact same way and at least in my opinion itâ€™s easier to understand what it does. Making this change wonâ€™t fix any problems, itâ€™s just a suggestion. If your current code is more readable to you, perhaps keep it the way it is.

``````local function checkNeighbors(x, y, z, map)
if x == 1 or y == 1 or z == 1 or x == MAPLEN_X or y == MAPLEN_Y or z == MAPLEN_Z then
return true
end
if not map[x][y][z] then
return true
end
for xx = -1, 1, 2 do
if not map[x + xx][y][z] then
return false
end
end
for yy = -1, 1, 2 do
if not map[x][y + yy][z] then
return false
end
end
for zz = -1, 1, 2 do
if not map[x][y][z + zz] then
return false
end
end
wait()
return true
end``````
1 Like

Your `culledMap` is a mixed table of array and dictionary parts, because any time `checkNeighbors()` returns true, youâ€™re not populating a spot in the array for that value of z. You have to assign a non-nil value for every x,y, and z with no gaps, or part of your arrays will be moved into the dictionary section of the table, even if the keys are integers.

Iâ€™m wondering if itâ€™s some quirk of how the tables are output in the Output window that youâ€™re not seeing the dictionary parts or something.

Iâ€™d try simply adding an `else` clause where you set culledMap[x][y][z] = Vector3.zero or something like that, to see if array sparseness is part of the problem.

1 Like

Yea that worked the first time, thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.