TTalma
TTalma

Reputation: 1

Is it possible to use a variable as a field name in a lua table?

I am new to Lua and am writing a program for a tool changer on my CNC machine. Each tool pocket's detail is stored as an entry in a table, the table looks like:

local PocketDetails = {
    PocketNumber = nil,
    X = nil,
    Y = nil,
    Z = nil,
    ClearX = nil,
    ClearY = nil,
    ClearZ = nil,
    ToolNumber = nil,
}

I want to be able to pass in the field name as a variable in a function (X, Y, Z, etc...) then have a function that will create the table entry, or update the existing field in the table as necessary. This function looks like:

function PocketPositions.UpdateField(pocketNumber, field, newVal )
    -- if there are no pockets add it
    if next(PocketDetails) == nil then
        table.insert(PocketDetails, {PocketNumber = pocketNumber, [field] = newVal})
    else
        local foundPocket = false
        -- look for pocket and update it
        local i = 1
        while PocketDetails[i] ~= nil and foundPocket == false do
            if PocketDetails[i].PocketNumber == pocketNumber then
                PocketDetails[i].[field]= newVal
            end
            i = i + 1
        end
        
        -- check to see if the pocket was in the array
        if foundPocket ~= true then
            -- pocket was not in the array add it
            table.insert(PocketDetails, {PocketNumber = pocketNumber, [field] = newVal})
        end
    end
end

The above does not compile due to the use of [field], But I am not sure how to do what I want. I would like to call the function like so (or something similar), from a button press. Some examples of possible calls:

PocketPositions.UpdateField(4, "X", 1.234)
PocketPositions.UpdateField(4, "Z", 5.678)
PocketPositions.UpdateField(2, "ClearX", 1.234)
PocketPositions.UpdateField(4, "X", 3.456)

Also if there is a better way to do the above I would like to see that

I've tried searching through examples here on stack exchange and the web and did not find anything similar to what I am trying to do. They were just single key value pairs in a table, it's possible I don't know the correct terminology for what I'm searching for.

I've tried replacing the [field] value with one of the field names in my function, and the function does what I want it to do.

Edit to add some details.

When the program starts PocketDetails = {} or is nil. The first time this function is called it will add some info to one of the pockets. At startup which pockets and which details will be populated is unknown.

The code:

table.insert(PocketDetails, {PocketNumber = pocketNumber, [field] = newVal})

throws the error: "table index is null"

After this code is called from PocketPositions.UpdateField(4, "X", 1.234) I am expecting this output:

local PocketDetails = {
PocketNumber = 4,
X = 1.234,
}

Upvotes: 0

Views: 93

Answers (1)

bbb234
bbb234

Reputation: 56

I suggest keeping track of all the pocket details in a larger table.

PocketPositions.AllPocketDetails = {}
-- keep track of all the pocket details here
-- can reference one of the details as 'PocketPositions.AllPocketDetails[pocketNum]'

function PocketPositions.UpdateField(pocketNum, field, newVal)
    local theseDetails = PocketPositions.AllPocketDetails[pocketNum]
    if theseDetails == nil then
        theseDetails = {
            PocketNumber = pocketNum,
            -- other default values can go here
        }
        theseDetails[field] = newVal
        PocketPositions.AllPocketDetails[pocketNum] = theseDetails
    else
        theseDetails[field] = newVal
    end
end

Upvotes: 0

Related Questions