Looping and adding chars to string in LUA - lua

It's about Lua/Roblox. (Disclaimer: must be roblox compatible.) I have an array called "array1", and a number value "num" which is 0.
local array1 = {"1","2","3","etc."}
local num = 0
I do:
while 1 do
wait(1) -- just a little delay between loops
num = num + 1 -- every loop I'm increasing that "num" value with 1.
script.Parent.TextLabel.Text = array1[num] -- I'm setting Text to [num]th (in this case 1) of array1. (I get 1st, 2nd, 3rd, 4th etc. word every second)
end
And it works. Kinda. My problem is, it's setting it to:
"1" and then only "2", not "1" and then "12".
Here's some video of the problem: https://i.imgur.com/d63BoN5.gifv
And I don't want it that way. I want to it to be:
1, 12, 123.

Try this:
script.Parent.TextLabel.Text = script.Parent.TextLabel.Text .. array1[num]
This will concatenate the previous Text value with the next number.

Related

save strings in lua table

Does someone know a solution to save the key and the values to an table? My idea does not work because the length of the table is 0 and it should be 3.
local newstr = "3 = Hello, 67 = Hi, 2 = Bye"
a = {}
for k,v in newstr:gmatch "(%d+)%s*=%s*(%a+)" do
--print(k,v)
a[k] = v
end
print(#a)
The output is correct.
run for k,v in pairs(a) do print(k,v) end to check the contents of your table.
The problem is the length operator which by default cannot be used to get the number of elements of any table but a sequence.
Please refer to the Lua manual: https://www.lua.org/manual/5.4/manual.html#3.4.7
When t is a sequence, #t returns its only border, which corresponds to
the intuitive notion of the length of the sequence. When t is not a
sequence, #t can return any of its borders. (The exact one depends on
details of the internal representation of the table, which in turn can
depend on how the table was populated and the memory addresses of its
non-numeric keys.)
Only use the length operator if you know t is a sequence. That's a Lua table with integer indexes 1,..n without any gap.
You don't have a sequence as you're using non-numeric keys only. That's why #a is 0
The only safe way to get the number of elements of any table is to count them.
local count = 0
for i,v in pairs(a) do
count = count + 1
end
You can put #Piglet' code in the metatable of a as method __len that is used for table key counting with length operator #.
local newstr = "3 = Hello, 67 = Hi, 2 = Bye"
local a = setmetatable({},{__len = function(tab)
local count = 0
for i, v in pairs(tab) do
count = count + 1
end
return count
end})
for k,v in newstr:gmatch "(%d+)%s*=%s*(%a+)" do
--print(k,v)
a[k] = v
end
print(#a) -- puts out: 3
The output of #a with method __len even is correct if the table holds only a sequence.
You can check this online in the Lua Sandbox...
...with copy and paste.
Like i do.

Generating all combinations from a table in Lua

I'm trying to iterate through a table with a variable amount of elements and get all possible combinations, only using every element one time. I've landed on the solution below.
arr = {"a","b","c","d","e","f"}
function tablelen(table)
local count = 0
for _ in pairs(table) do
count = count + 1
end
return count
end
function spellsub(table,start,offset)
local str = table[start]
for i = start+offset, (tablelen(table)+1)-(start+offset) do
str = str..","..table[i+1]
end
return str
end
print(spellsub(arr,1,2)) -- Outputs: "a,d,e" correctly
print(spellsub(arr,2,2)) -- Outputs: "b" supposed to be "b,e,f"
I'm still missing some further functions, but I'm getting stuck with my current code. What is it that I'm missing? It prints correctly the first time but not the second?
A solution with a coroutine iterator called recursively:
local wrap, yield = coroutine.wrap, coroutine.yield
-- This function clones the array t and appends the item new to it.
local function append (t, new)
local clone = {}
for _, item in ipairs (t) do
clone [#clone + 1] = item
end
clone [#clone + 1] = new
return clone
end
--[[
Yields combinations of non-repeating items of tbl.
tbl is the source of items,
sub is a combination of items that all yielded combination ought to contain,
min it the minimum key of items that can be added to yielded combinations.
--]]
local function unique_combinations (tbl, sub, min)
sub = sub or {}
min = min or 1
return wrap (function ()
if #sub > 0 then
yield (sub) -- yield short combination.
end
if #sub < #tbl then
for i = min, #tbl do -- iterate over longer combinations.
for combo in unique_combinations (tbl, append (sub, tbl [i]), i + 1) do
yield (combo)
end
end
end
end)
end
for combo in unique_combinations {'a', 'b', 'c', 'd', 'e', 'f'} do
print (table.concat (combo, ', '))
end
For a tables with consecutive integer keys starting at 1 like yours you can simply use the length operator #. Your tablelen function is superfluous.
Using table as a local variable name shadows Lua's table library. I suggest you use tbl or some other name that does not prevent you from using table's methods.
The issue with your code can be solved by printing some values for debugging:
local arr = {"a","b","c","d","e","f"}
function spellsub(tbl,start,offset)
local str = tbl[start]
print("first str:", str)
print(string.format("loop from %d to %d", start+offset, #tbl+1-(start+offset)))
for i = start+offset, (#tbl+1)-(start+offset) do
print(string.format("tbl[%d]: %s", i+1, tbl[i+1]))
str = str..","..tbl[i+1]
end
return str
end
print(spellsub(arr,1,2)) -- Outputs: "a,d,e" correctly
print(spellsub(arr,2,2)) -- Outputs: "b" supposed to be "b,e,f"
prints:
first str: a
loop from 3 to 4
tbl[4]: d
tbl[5]: e
a,d,e
first str: b
loop from 4 to 3
b
As you see your second loop does not ran as the start value is already greater than the limit value. Hence you only print the first value b
I don't understand how your code is related to what you want to achieve so I'll leave it up to you to fix it.

What does a "for i, v" loop do?

I understand, "for i, v" loops for tables, i is the index, and v is the value, but what does this script do? I do not think this has anything to do with tables, but the only type of for table loops I know in ROBLOX script is the first one I mentioned; "for i, v" loops, which loop through tables.
randomVariable = 1
for i = 1, randomVariable do
(random script)
end
This is a numeric loop statement.
for controlValue = startValue, endValue, stepValue do
-- for body
end
It goes from startValue until it reaches endValue, after running body code, controlValue is increased by stepValue. If controlValue is higher or equals to endValue the loop stops. If stepValue is not provided, it equals to 1.
It's equivalent to this code:
local controlValue = startValue
if not stepValue then stepValue = 1 end -- if no stepValue it equals to 1
while controlValue < endValue do
-- for body
controlValue = controlValue + stepValue
end
There are a few different ways to loop in Lua.
while variable < number do
repeat stuff until variable == number
for key, value in pairs do
for index, value in ipairs do
for i = 1, number do
i = 1 is the initial condition.
It usually begins at one, then loops through items in a table.
So you can think of it as an index in that regard.
where the randomVariable you mentioned would be #tab
however, you could set that initial condition to be larger, then count down.
for i = #tab, 1, -1 do
the third, optional argument is called "step size"
and it's the amount that initial condition is changed, after completing each loop. it defaults to 1, so it's not needed, most of the time.
so to step through all the even numbers in a table it would be
for i = 2, #tab, 2 do
Further reading: https://www.tutorialspoint.com/lua/lua_loops.htm

how to "page" through the data in a Lua table used as a dictionary?

How would I code a function to iterate through one "pages" worth of data? Sample code would be ideal...
So say we image the size of a page is 5 items. If we had a lua table with 18 items it would need to print out:
Page 1: 1 to 5
Page 2: 6 to 10
Page 3: 11 to 15
Page 4: 16 to 18
So assume the data is something like:
local data = {}
data["dog"] = {1,2,3}
data["cat"] = {1,2,3}
data["mouse"] = {1,2,3}
data["pig"] = {1,2,3}
.
.
.
How would one code the function that would do the equivalent of this:
function printPage (myTable, pageSize, pageNum)
-- find items in "myTable"
end
So in fact I'm not even sure if a Lua table used as a dictionary can even do this? There is no specific ordering is there in such a table, so how would you be sure the order would be the same when you come back to print page 2?
The next function allows you to go through a table in an order (albeit an unpredictable one). For example:
data = { dog = "Ralf", cat = "Tiddles", fish = "Joey", tortoise = "Fred" }
function printPage(t, size, start)
local i = 0
local nextKey, nextVal = start
while i < size and nextKey ~= nil do
nextKey, nextVal = next(t, nextKey)
print(nextKey .. " = " .. nextVal)
i = i + 1
end
return nextKey
end
local nextPage = printPage(data, 2) -- Print the first page
printPage(data, 2, nextPage) -- Print the second page
I know this isn't quite in the form you were after, but I'm sure it can be adapted quite easily.
The next function returns the key after the one provided in the table, along with its value. When the end of the table is reached, it returns nil. If you provide nil as the second parameter, it returns the first key and value in the table. It's also documented in Corona, although it appears to be identical.

Strange table error in Lua

Okay, so I've got a strange problem with the following Lua code:
function quantizeNumber(i, step)
local d = i / step
d = round(d, 0)
return d*step
end
bar = {1, 2, 3, 4, 5}
local objects = {}
local foo = #bar * 3
for i=1, #foo do
objects[i] = bar[quantizeNumber(i, 3)]
end
print(#fontObjects)
After this code has been run, the length of objects should be 15, right? But no, it's 4. How is this working and what am I missing?
Thanks, Elliot Bonneville.
Yes it is 4.
From the Lua reference manual:
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
Let's modify the code to see what is in the table:
local objects = {}
local foo = #bar * 3
for i=1, foo do
objects[i] = bar[quantizeNumber(i, 3)]
print("At " .. i .. " the value is " .. (objects[i] and objects[i] or "nil"))
end
print(objects)
print(#objects)
When you run this you see that objects[4] is 3 but objects[5] is nil. Here is the output:
$ lua quantize.lua
At 1 the value is nil
At 2 the value is 3
At 3 the value is 3
At 4 the value is 3
At 5 the value is nil
At 6 the value is nil
At 7 the value is nil
At 8 the value is nil
At 9 the value is nil
At 10 the value is nil
At 11 the value is nil
At 12 the value is nil
At 13 the value is nil
At 14 the value is nil
At 15 the value is nil
table: 0x1001065f0
4
It is true that you filled in 15 slots of the table. However the # operator on tables, as defined by the reference manual, does not care about this. It simply looks for an index where the value is not nil, and whose following index is nil.
In this case, the index that satisfies this condition is 4.
That is why the answer is 4. It's just the way Lua is.
The nil can be seen as representing the end of an array. It's kind of like in C how a zero byte in the middle of a character array is actually the end of a string and the "string" is only those characters before it.
If your intent was to produce the table 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 then you will need to rewrite your quantize function as follows:
function quantizeNumber(i, step)
return math.ceil(i / step)
end
The function quantizeNumber is wrong. The function you're looking for is math.fmod:
objects[i] = bar[math.fmod(i, 3)]

Resources