2

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?

2
  • 3
    I can't even figure how did you get from first snippet to second. Try formulating every step. You'll have almost ready program with only few words to change from English to Lua syntax. Commented Sep 20, 2012 at 8:50
  • I didn't get from the first block to the second - that's my question. I simply wanted to show the structure that I (think I) need, so I wrote the Lua table by hand, Commented Sep 20, 2012 at 9:26

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

I wish I could accept both answers; they complement each other - yours provides the explanation, Giant's the code. Thank you both. And you're quite right about the double nested structure; I found writing this table by hand pretty cumbersome...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.