DEV Community

Danny Guo
Danny Guo

Posted on • Originally published at dannyguo.com on

How to Concatenate Strings in Lua

The most straightforward way to concatenate (or combine) strings in Lua is to use the dedicated string concatenation operator, which is two periods (..).

message = "Hello, " .. "world!" -- message equals "Hello, World!" 
Enter fullscreen mode Exit fullscreen mode

Numbers are coerced to strings. For fine-grained control over number formatting, use string.format, which behaves mostly like C's printf.

count = 42 message = "The count is: " .. count -- message equals "The count is: 42" 
Enter fullscreen mode Exit fullscreen mode

Trying to concatenate other types, like nil or a table, will result in an error.

count = nil message = "The count is: " .. count -- results in an "attempt to concatenate a nil value" error 
Enter fullscreen mode Exit fullscreen mode

Note that Lua doesn't have syntactic sugar for augmented assignment. The following is invalid syntax.

message = "Hello, " message ..= "world!" -- results in a "syntax error near '..'" error 
Enter fullscreen mode Exit fullscreen mode

Strings in Lua are immutable, so the concatenation result (message in this example) is a brand new string.

start = "Hello, " message = start .. "world!" start = "Bye, " -- message still equals "Hello, World!" 
Enter fullscreen mode Exit fullscreen mode

table.concat

If you need to perform many concatenation operations, using the concatenation operator can be slow because Lua has to keep reallocating memory to create new strings.

message = "" for i=1,100000 do message = message .. i end 
Enter fullscreen mode Exit fullscreen mode

As a result, it can be much faster to use table.concat.

numbers = {} for i=1,100000 do numbers[i] = i end message = table.concat(numbers) 
Enter fullscreen mode Exit fullscreen mode

Here's a benchmark comparsion (using hyperfine) from running the .. example as slow.lua and running the table.concat example as fast.lua.

hyperfine 'lua slow.lua' # Benchmark #1: lua slow.lua # Time (mean ± σ): 1.287 s ± 0.115 s [User: 1.120 s, System: 0.078 s] # Range (min … max): 1.187 s … 1.528 s 10 runs hyperfine 'lua fast.lua' # Benchmark #1: lua fast.lua # Time (mean ± σ): 39.3 ms ± 3.8 ms [User: 34.6 ms, System: 2.8 ms] # Range (min … max): 35.3 ms … 58.3 ms 48 runs 
Enter fullscreen mode Exit fullscreen mode

The difference probably doesn't matter in most cases, but it's a good optimization to be aware of.

table.concat can also be easier to use because it can take a separator argument to add between elements.

message = table.concat({1, 2, 3, 4, 5}) -- message equals "12345" message = table.concat({1, 2, 3, 4, 5}, ", ") -- message equals "1, 2, 3, 4, 5" 
Enter fullscreen mode Exit fullscreen mode

It can also take start and end indexes. Keep in mind that Lua arrays start with index 1.

message = table.concat({1, 2, 3, 4, 5}, ", ", 2, 4) -- message equals "2, 3, 4" 
Enter fullscreen mode Exit fullscreen mode

Direct Approach

Depending on your use case, you might be able to save some memory usage over table.concat by generating the result directly.

for i=1,100000 do io.stdout:write(i) end 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)