I don’t quite understand what your trying to do. The code you provided would error since the table is an array, so value would point to the string “hello” and not a table, so you’d get a key error when you try to call value.tableParent.
local a = 'hello' -- this has a specific memory address
local b = 'hello' -- this has a different memory address
local tbl = {a, 'hi there'}
print(table.getArrays(a)) -- Prints: {{'hello', 'hi there'}}
print(table.getArrays(b)) -- Prints: {}
The reason they don’t is because an array just stores stuff. It’s like a shelf with a bunch of unlabeled boxes on it. You can open the first box to find pencils inside, and then the second to find paper, but none of the boxes will contain a list of what’s on the shelf unless you put it in there.
I’m not sure whether this specifically will work for you since I don’t know your exact implementation, but the basic principle is that you can wrap every value of the array into objects that hold a reference to the parent array; something like this:
-- this actually won't work since tbl is nil, but I'm trying to show you how the table will look like
-- I will show you later in this post how to make this work
local tbl
tbl = {
{value = 'hello', tableParent = tbl}, -- "wrap" the original value into an object
{value = 9, tableParent = tbl},
{value = true, tableParent = tbl}
}
local obj = tbl[1]
print(obj.value) -- Outputs: 'hello'
-- these print the same table
print(tbl)
print(obj.tableParent)
Now we just need to set up every table like this. We need to account for two scenarios: converting a normal table and adding new values to a table.
Converting a normal table
Basically just a function that takes an existing array and replaces the values with objects.
local function convertArr(arr)
for i, v in ipairs(arr) do
arr[i] = {value = v, tableParent = arr}
end
return arr
end
Using this method, you can call convertArr on new tables directly:
local tbl = convertArr({
'hello',
9,
true
})
local obj = tbl[1]
print(obj.value) -- Outputs: 'hello'
-- these print the same thing
print(tbl)
print(obj.tableParent)
Or pass an already existing table like so:
local tbl = {
'hello',
9,
true
}
convertArr(tbl) -- this achieves the same thing as the above example (tbl is passed by reference)
Adding new values to the table
This is needed if you plan on adding values to a table after it’s initialized. This is easiest with a metatable:
local mt = {
__newindex = function(arr, index, val)
rawset(arr, index, {value = val, tableParent = arr})
end
}
We can do this now:
local tbl = convertArr({
'hello',
9,
true
})
setmetatable(tbl, mt)
tbl[4] = "new value" -- the __newindex metamethod creates the wrapper object for us
local obj = tbl[4]
print(obj.value) -- Outputs: "new value"
-- this still works the same way it did before
print(tbl)
print(obj.tableParent)
The catch
Toggle
Keep in mind that if you want to modify a table like this, you’ll have to modify the value field of the object:
tbl[1].value = "goodbye"
Fortunately, we can create another function to make this easier (mutator function):
local function modifyValue(arr, index, val)
arr[index].value = val
end
Sidenote (which might actually be the solution, idek)
Toggle
This is also something you might be able to create on your own. Something kind of like this:
local function add(arr, obj) -- this could be in a module instead
table.insert(arr, obj)
table.insert(obj.arrays, arr)
end
Since you’re using classes of your own you could perhaps add an arrays field to them that stores references to all the arrays they are in. You then of course create your own getArrays method which simply returns the arrays field.