adding quotation marks to elements in a table

I’m trying to convert a table that looks like this: {cat, dog, spider, duck}
into one that looks like this: {“cat”, “dog”, “spider”, “duck”}

I tried this:

for i = 1, #oldtable
     newtable[i] = \"..oldtable[i]..\"

…and that didn’t work at all.

How many mistakes am I making here?
Is " the correct way to refer to a quotation mark?
Is that concatenation line messed up somehow?
Am I even allowed to store strings w/o quotes in a table?

Try this instead:

for i = 1, #oldtable
     newtable[i] = "\""..oldtable[i].."\""

(Your quotes need to be inside quotes)

I wonder if what I’m trying to do just shouldn’t be done. So far I’m unable to access an element in my table, when that element is a string-without-quotes.

This works:

function setup()
   lacksquotes = {2, 3, frog}
   withquotes = {}
   withquotes[1] = "\""..lacksquotes[1].."\""

It dutifully prints out: “2”

But when I change the table to lacksquotes = {frog, 2, 3} then it chokes on the concatenation line, with the error text “attempt to concatenate field ‘?’ (a nil value)”.

It seems like the concatenation makes Codea want to take a closer look at the contents of the table, and once it looks it doesn’t like what it sees.

Is there some other way to alter the contents of a table, when those contents are in a format that Codea isn’t going to like?

Your ‘strings without quoted’ are simply variables. So your concatenation error is an indication that Codea is trying to look at the value stored within your ‘frog’ variable. Because nothing has ever been stored in that variable, its value is nil, and can’t be used in a concatenation.

So you’re essentially storing nil in your table, like this:

frog = nil
lacksQuotes = {2, 3, frog}

I’m not hugely familiar with Lua, so I don’t know whether it offers the functionality you’re after, sorry!

Thanks frosty. Yeah, you’ve worded it better, but that’s what I was starting to realize.

So what I’m looking for is a way to get Codea to reach into the table with its eyes closed, so that it doesn’t even notice those are variables, slap some quotes around each element, and THEN look inside and go “ooh, strings! just what I wanted!”

There miiiight be a way to do it with the Lua debug library, which has been included in version 1.3.5 of Codea, but I’ll have to read up on it :slight_smile:

nope, no way. You want perl’s qw//, but something like that is not available in lua at the point when the code runs. For the vanilla interpreter there is a patch that hooks into the lexer, allowing you to filter or change tokens, but that one is not available for codea and I’m not sure wether it should be.

Maybe if you could explain the context a little more then it might be possible to come up with an alternative method for what you are doing. For example, why do you have frog as a bare word? Where does this come from, and why can’t you just type "frog" in the first place?

Here’s some context: I’m working on a quiz program that displays “question text” and “answer text”. I want to import a variety of quiz sets, some with hundreds of elements. Adding quotes to each element takes a lot of time, so I’d prefer to automate the process.

I figured this was really a job for perl, but I’d prefer to have the function built-in, so that I could hand someone my code and they could create their own data sets with a minimum of formatting.

I’ve settled on a small compromise, where I enter all the text as one long string, then break it up based on the commas. (I’m assuming this code is clunky and inefficient, based on my still-quite-limited lua knowledge.)

function setup()
    	words = {}
    	for i = 1,#quizdata do
		if string.byte(quizdata,i) == 44 then     -- found a comma
			j = j + 1 --    move on to next slot in words table
		else   -- not a comma, add letter to current word
			words[j] = words[j]..string.sub(quizdata,i,i) 
    	   -- test that all is well in there
	for i = 1,#words do

Other than the fact that this will all fall apart at the slightest typo, I think this just might work.

Just popping back in to say that while the above code is functional, it’s also very slow. My app pauses for a good eight seconds (while reading in a data list of around 100 items) before displaying anything.

If any of you expert lua coders have suggestions for simplifying / streamlining the string-splitting process, I’d love to hear it.

I’m also wondering why my attempts at a “loading” screen aren’t working. In my setup() function I assign a background, set my text size and fill, and make a text call of “Loading…”, all before calling the function that does the text processing shown above.

And yet, when I run the app I get eight seconds of a black screen, followed by a very brief flash of the word “Loading”, and then the main app runs. Is the setup() function unable to draw to the screen until the first draw() cycle?

The code executes quite fast for me. About 0.004 seconds for 100 words.

The slowest part is actually printing out all the words at the end — printing in a loop is still quite slow in Codea.

@Goatherd hacking the string apart might be faster like this:

words = {}
j = 1
string.gsub(quizdata, "([^,]+)", function(x) words[j] = x j=j+1 end)

creating strings by concatenating individual characters in a loop is bound to become very slow if a lot of strings very long strings are generated, because for every s=s…c lua creates a new string, interns it, and the old string becomes garbage. So even for more complex parsing stuff, just keeping track of the indices and extracting the tokens you need using string.sub is a lot faster. For simple stuff, like the above, string.gsub is just fine.

@gunnar_z Thanks, I’ll try that!

@Simeon Oh wow, you are totally right. I still had that print loop in there, to test that it was working, and that’s exactly what was slowing it down! How embarrassing. Thanks for the help.