Lua for GrandMA3 Episode 6 - Generic For Loops
Hey lighting folks! The following is the transcript from my YouTube video, Lua for MA3 Ep 6 - Generic For Loops
This video is part of my Lua for GrandMA3 Tutorial series. Please check out my channel, From Dark To Light, on YouTube, and you can find the code to go along with my tutorials here on GitHub.
Hello lighting people! Welcome back to my Lua for GrandMA3 tutorial series. Today we're going to be jumping through all kinds of hoops. Hoops? Wait, loops! Oh and there's no jumping involved actually, we're just talking about loops; by continuing on the topic of tables, which I've been talking about for the last two videos, and specifically I'm going to explain how the generic for loop works. Note that I specified “generic” for loop; the reason is because there are two types of for loops, “numeric” and “generic.” Generic for loops are the only ones that are specific to use with tables, so we're going to focus on these today.
Basically a generic for loop is a tool to go through the keys, or indices, of a table and give you information about each entry, and for some applications it's a lot faster than calling each index individually. Just to make this clear, “indices” and “keys” are basically two words for the same thing and I'll be using them interchangeably.
Let's go ahead and get started. The basic syntax for a generic for loop is going to be “for var, optionalVar” – I'm just using these as placeholders for now – “in pairs(table) do --my actions end”
So that would be basically how a for loop is made. There are two built-in functions in Lua to be used with the generic for loop and “pairs” is one of of them. Basically both of them do the same thing but there's an important difference I'll explain shortly.
To back up a little bit, let's review what we know about tables. I’m going to create a table here. One way you could create a table would be like this: “myTable =” - we'll put “{10, 20, 30, 40, 50}”
This kind of table is also known as an array. I didn't specify the keys for these values, so they get automatically assigned keys 1, 2, 3, 4 and 5 in that order. If I add another value; let's say I go down here and do “table.insert(myTable, 60)” then the new value is added at key 6.
A more familiar and
often more useful way for us to make a table would be like this:
“myInfo = {name = ‘John Doe’, age = ‘36’, birthplace =
‘United States’}”
In this case these values are
specifically assigned to the keys “name” and “age” and
“birthplace.”
Now I'm going to plug the first of those two tables into a generic for Loop and explain what it does. In this case I'm going to use the “ipairs” function and it's just written like that: “ipairs” and for right here I'm going to put the name of the table, which is “myTable” and then here we're going to go… I'm actually going to change these from “var, optionalVar” to “key, value.” You'll also see people just do “k, v.” And then right here I'll do “Printf(‘This is my value: ’ .. value)”
As you can see that's the variable I put right here. Basically what this does is it goes through my table starting at index 1 and temporarily stores the index and value in the corresponding variables, “key” and “value;” I could have named these values anything, it'll do the same thing. So it finds index 1, that would be right here, notes that the key is 1 and the value is 10, and uses that information to perform the task inside the loop, which in this case is printing the value. So we go, “for index 1, value 10, do this,” and we're going to print “value” and then it goes on to the next index, 2, and does the same thing, and so on. Once it reaches an index that doesn't exist then the loop just ends.
Just to show you how this works I will run it in MA3 and as you can see, it printed key 1, key 2, key 3, key 4, key 5; those values. And you could totally also do something with the key. You could print the key and the value if you actually wanted to.
So this ipairs function is great; this is basically how it works. You'll use it the same way no matter what you're doing inside of here. The only problem with it is that it only works with arrays like that, that actually have numeric keys. If you tried it with the “myInfo” table it simply wouldn't work. It would look for key 1 and not find it and end immediately. Instead you have to use this version.
I'll leave this for loop here so you can refer back to it and do a separate one. This one is going to say, “for key, value in pairs(myInfo) do Printf” – I'm going to go “(‘Key: ’ .. key .. ‘ Value: ’ .. value)” and let's go run this one.
As we can see we got the same output as before, and then we had this “Key: age Value: 36 Key: name Value: John Doe Key: birthplace Value: United States.”
To make an example of how this can be super helpful I'm going to make a fairly simple MessageBox function that includes inputs. These return tables with key/value pairs, so to list out the values instead of typing out “Printf(returnTable.inputs[1] Printf(returnTable.inputs[2]” etc. like we would otherwise have to, let's use the for loop instead, so I'm going to create a MessageBox, and you do this by setting a variable, I'll use a local variable, called “returnTable” equal to the results of the function, MessageBox, and then we put our table in here with a title and, why not, put a comma and then the next value. I'm not even going to bother putting a message in here, I'm just going to go ahead and put some inputs in here, so I'm going to create inputs equal to – remember you have to have a table – and then a table for each input, and for this input the information I'm going to use is going to be a name, which will be “Input 1,” a value… I'll just put a default value of nothing, and vkPlugin will be TextInput; that's just kind of the default normal one.
And I'm actually going to throw this in here now just so that you know, if you don't put a maxTextLength you might have a bug cause it to have a limited max text, and I don't know why but I did have this for a while where all of my inputs would only let me put in two characters on my lighting console. On my onPC it worked fine, but on the console I could only do a maximum of two characters, and by simply setting a maxTextLength I was able to get around that, so now I just always put a maxTextLength, even if it's 100 characters, it's just really good to have that so that it won't mess up in case it somehow messes up.
Let's do another one: “name = ‘Input 2’, value = ‘Something’” because I like to have fun that way, and then “vkPlugin = ‘TextInput’” and “maxTextLength = 100” and then, just one more, “name = ‘Input 3’, value = ‘3’” because I can, right? “vkPlugin = ‘TextInput’, maxTextLength = 100”
Okay that was a lot! Now we do have to put a command in here just to get it to close, and we'll go, “commands =” - again, same thing, two sets of braces. I'll just go “name = ‘Okay’, value = 1”
Alright, now I've created my MessageBox, and just to give you a visual, what we would normally have to do to get each of these inputs returned individually would be, “Printf(returnTable.inputs)” and then put the index here, so that would be “[1]” and then the same thing with the index “2” and the same thing with the index “3” and that's a lot!
So instead I actually have a better solution, and that is a for loop. Let's try it. “for key, value in pairs(returnTable.inputs)” – remember you do want to make sure you get the table of inputs, not the main return table, because the main return table will give you “inputs” as a key and a table as a value, and you can't print a table. Close that, type “do” and then “Printf(value)” – obviously you could put other information here, but I just want to get the value printed right now, “end” and let's copy and paste that.
Alright, we have three inputs, and if I hit “Okay” right now we're going to see “3,” a blank space, and “Something.” The reason for this is because inputs actually get ordered alphabetically, so I guess it's placing the blank space as after the numeric value and before the S. Now suppose in input 1 I put “abc” and then in input 3 I put “another value,” then it's listing them... Okay, that's actually really curious. I have no idea why it's putting “another value” before “abc” because that's not alphabetically correct.
But again, you put inputs into your table and you get a result, whatever that result may be, and I guess it's just confused about “another value” honestly because, I mean, it's ordering them alphabetically aside from that and that does not make sense to me, so I guess that's interesting.
The point is, it's way easier than actually typing out “Printf(this value)” for every value, especially when you have a whole bunch of inputs; or maybe you don't know how many you have. This will go through all of them, however many there may be.
I'm very excited about how much ground we've already covered, but in the next episode we're going to be talking about loops again; in this case, numeric for loops. I use numeric for loops way more often than generic for loops, and they're also quite a bit simpler, so I can't wait to share them with you. Until then, I hope you have a great rest of your day and I'll see you in the next video!
Comments
Post a Comment