Hi, getting some really weird behaviour which may be a Lua thing...?
I'm finding the index of a int value in a table using:
if indexOf(self.levelAvailable, self.cursorCoord) then
-- do something
self.levelAvailable[index] = nil
end
However, sometimes it just doesnt find it...I'm making a grid based sokoban type game and there are 4 or so available tiles and most of the time it fails to find them after a few have been set.
I don't know a whole lot about the implementation details of Lua. But the documentation for tables seems to indicate that lua doesn't care if a table is a sequence or not. Lua Manual 5.4 Values & Types
It points to the length operator which is only available on a table if it's a sequence, offers a more in-depth answer about how lua works if you're treating a table like an array. (Which it looks like you might be?) https://www.lua.org/manual/5.4/manual.html#3.4.7
Is cursorCoord an integer or a table? If it's a table (e.g. vector) you're comparing table ids instead of their values. It's also completely possible that table.indexOfElement stops when it hits nil. I guess that case would qualify as an SDK bug.
Generally speaking there are no arrays in the Lua language and an array-like table simply contains integer keys 1..N. Under the hood Lua does all sorts of optimization tricks and even uses actual C arrays, but you don't really need to care about those. In Lua you're always working with tables that are like objects or dictionaries in other languages.
Yes self.cursorCoord is an int. I was expecting the index of value to still work well enough if there was a table (array) of values, where most have been set to nil bar one or two, this is not teh case it seems... which is fine. table.remove works, just odd.
Overthinkig what does it even mean to find index of element in a table
The type table implements associative arrays, that is arrays that can be indexed not only with numbers, but also with strings or other values.
Regardless of key type any key associated to the value nil is not considered to be part of the table. It is an absent key. But there are different ways to iterate over absent keys of different types.
Indexed Array
Associative Array (Hash Map)
Keys
Sequential integers (1, 2, 3…)
Arbitrary (strings, numbers, mixed)
tbl[1], tbl[2], tbl[3]
tbl["name"], tbl[{1,2}], tbl[3.5]
Iterating with
for i = 1, #tbl or ipairs()
pairs()
ipairs assumes that table is representing regular indexed array and that it ends just before its first nil element. It will iterate sequentially over the key–value pairs up to the first absent key.
function indexOfElementIPairs(tbl, value)
for i, v in ipairs(tbl) do
if v == value then
return i
end
end
return nil
end
Watch ipairs bailing out after 2nd key
With for loop we can iterate numerically from 1 to the length of the table
function indexOfElementFor(tbl, value)
for i = 1, #tbl do
if tbl[i] == value then
return i
end
end
return nil
end
Length operator applied on a table returns a border - index of an element just before absent key. It doesn't keep track of all absent keys, or all borders. It just looks for any border.
If table has more then one border, it doesn't guarantee to return any specific one.
Here are some tables with 3 borders and length operator being its best non-deterministic self
pairs will iterate over all key–value pairs of table, in no particular order, but skipping absent keys
Moral of the story:
arrays are not supposed to contain nil values
table.remove() works because its doesn't just delete element but also shifts all of consequent elements to fill the hole in a table
use pairs(tbl) to iterate over weird unordered stuff