In many languages you can concatenate strings on variable assignment. I have a scenario, using the Lua programming language, where I need to append the output of a command to an existing variable. Is there a functional equivalent in Lua to the below examples?
Examples of other languages:
===== PERL =====
$filename = "checkbook";
$filename .= ".tmp";
================
===== C# =====
string filename = "checkbook";
filename += ".tmp";
===============
Thank you in advance for your help.
As other answers have said, the string concatenation operator in Lua is two dots.
Your simple example would be written like this:
filename = "checkbook"
filename = filename .. ".tmp"
However, there is a caveat to be aware of. Since strings in Lua are immutable, each concatenation creates a new string object and copies the data from the source strings to it. That makes successive concatenations to a single string have very poor performance.
The Lua idiom for this case is something like this:
function listvalues(s)
local t = { }
for k,v in ipairs(s) do
t[#t+1] = tostring(v)
end
return table.concat(t,"\n")
end
By collecting the strings to be concatenated in an array t
, the standard library routine table.concat
can be used to concatenate them all up (along with a separator string between each pair) without unnecessary string copying.
Update: I just noticed that I originally wrote the code snippet above using pairs()
instead of ipairs()
.
As originally written, the function listvalues()
would indeed produce every value from the table passed in, but not in a stable or predictable order. On the other hand, it would include values who's keys were not positive integers in the span of 1
to #s
. That is what pairs()
does: it produces every single (key,value) pair stored in the table.
In most cases where you would be using something like listvaluas()
you would be interested in preserving their order. So a call written as listvalues{13, 42, 17, 4}
would produce a string containing those value in that order. However, pairs()
won't do that, it will itemize them in some order that depends on the underlying implementation of the table data structure. It is known that the order not only depends on the keys, but also on the order in which the keys were inserted and other keys removed.
Of course ipairs()
isn't a perfect answer either. It only enumerates those values of the table that form a "sequence". That is, those values who's keys form an unbroken block spanning from 1 to some upper bound, which is (usually) also the value returned by the #
operator. (In many cases, the function ipairs()
itself is better replaced by a simpler for
loop that just counts from 1
to #s
. This is the recommended practice in Lua 5.2 and in LuaJIT where the simpler for
loop can be more efficiently implemented than the ipairs()
iterator.)
If pairs()
really is the right approach, then it is usually the case that you want to print both the key and the value. This reduces the concerns about order by making the data self-describing. Of course, since any Lua type (except nil
and the floating point NaN
) can be used as a key (and NaN
can also be stored as a value) finding a string representation is left as an exercise for the student. And don't forget about trees and more complex structures of tables.