Thomas
Thomas

Reputation: 249

how to populate nested tables in Lua?

This must be embarrassingly easy, but I can't find the solution: I have a text file with data in this form:

| 1 | 1 | A | X |
|   | 2 | A | Z |
|   |   | B | Y |

I would like to process this data with Lua, so I need to have it in a structured (nested) table like this (I hope the indentation comes out right):

t = {
    ['1'] =
    {  
        ['1'] = 
        {
            {
                { ['A'] = 'X' },
            },
        },
        ['2'] = 
        {
            {
                { ['A'] = 'Z' },
                { ['B'] = 'Y' },
            },
        },
    },
}

But I can't figure out how to go from A to B. The structure is already kind of there, but how can I read it into Lua?

Upvotes: 2

Views: 714

Answers (2)

hjpotter92
hjpotter92

Reputation: 80629

This will definitely do the task for you.

tTable = {}
OldIDX, OldIDX2, bSwitched, bSwitched2 = 0, 0, false, false

for str in io.lines("txt.txt") do
    local _, _, iDx, iDex, sIdx, sVal = str:find( "^%| ([%d|%s]?) %| ([%d|%s]?) %| (%S?) %| (%S?) %|$" )
    if not tonumber(iDx) then iDx, bSwitched = OldIDX, true end
    if not tonumber(iDex) then iDex, bSwitched2 = OldIDX2, true end
    OldIDX, OldIDX2 = iDx, iDex
    if not bSwitched then
        tTable[iDx] = {}
    end
    if not bSwitched2 then
        tTable[iDx][iDex] = {}
    end
    bSwitched, bSwitched2 = false, false
    tTable[iDx][iDex][sIdx] = sVal
end

NOTE

The only thing you can change in the code is the name of the file. :)

EDIT

Seems like I was wrong, you did need some changes. Made them too.

Upvotes: 2

mtsvetkov
mtsvetkov

Reputation: 843

Assuming you can read in a line and get to the individual items between the |'s, the algorithm would be something like this (pseudo code, I'll use col(n) to indicate the character in the n'th column for the current line):

1. store current indices for columns 1 and 2 (local vars)
2. read line (if no more lines, go to 7.)
3. if col(1) not empty - set the currentCol1 index to col(1)
    a. if t[currentCol1] == nil, t[currentCol1] = {}
4. if col(2) not empty - set the currentCol2 index to col(2)
    a. if t[currentCol1][currentCol2] == nil, t[currentCol1][currentCol2] = {}
5. set t[currentCol1][currentCol2][col(3)] = col(4)
6. go to step 2.
7. return t

I hope this is mostly self explanatory. Except for step 2 you shouldn't have problems going from pseudo-code to lua (and we don't know how you're getting to that data to help you with step 2). If you're not sure about the able operations, I'd suggest going over "Tables as arrays" and "Tables as dictionaries" from this lua-users tutorial.

As a side note - your example seems to be double-nesting the A=X,A=Z,B=Y inside two tables. I suspect that instead of:

['2'] = 
    {
        {
            { ['A'] = 'Z' },
            { ['B'] = 'Y' },
        },
    },

you meant:

['2'] = 
    {
        { ['A'] = 'Z' },
        { ['B'] = 'Y' },
    },

so that's what the pseudo code should get you.

Upvotes: 1

Related Questions