I've rewritten table.concat, making use of a new function I wrote. This allows you to have a nil value in your table, such as
display(stuff)
table {
1: 5
2: 50
3: 52
8: 31
}
In the above, notice keys 4 - 7 are nil. We can either make use of
table.condense to rewrite this table, or we can make it simply return the condensed form without rewriting. The new
table.concat makes use of it without rewriting.
table.concat (table [, sep [, i [, j [,skiptable]]]])
Given an array where all elements are strings, numbers, OR NIL, returns table..sep..table[i+1] ··· sep..table[j], skipping the nil values. The default value for sep is the empty string, the default for i is 1, and the default for j is the length of the table. If i is greater than j, returns the empty string. If skiptable is true, tables will be skipped instead of generating an incorrect type error. Default for skiptable is true.
table.condense(table [,rewrite])
Given a table, it will condense it to the correct form for an ipairs to handle. If rewrite is true, it will rewrite it to the table. If rewrite is false, it will return the condensed form. The default for rewrite is true.
function table.concat(tab,del,min,max,skiptable)
--these check to make sure the arguments are correct.
assert(type(tab) == "table",
"Bad argument #1 to 'concat'. (table expected, got "..type(tab)..")")
assert(type(del) == "string" or type(del)== "nil" or type(del)=="number",
"Bad argument #2 to 'concat'. (string expected, got "..type(del)..")")
assert(type(min) == "number" or type(min)=="nil",
"Bad argument #3 to 'concat'. (number expected, got "..type(min)..")")
assert(type(max) == "number" or type(max)=="nil",
"Bad argument #4 to 'concat'. (number expected, got "..type(max)..")")
if type(skiptable) ~= "boolean" then skiptable = true end
local tab = table.condense(tab, false)
local concated = nil
local del = del or ""
local min = min or 1
max = max or #tab
for key,val in ipairs(tab) do
local typ = type(tab[key])
if key>=min and key<=max then
if typ == "string" or typ=="number" or typ=="nil" then
if tab[key]~=nil then
concated = (not concated and val) or (concated .. del .. val)
end
elseif not skiptable then
error("invalid value ("..typ..") at index "..key..[[ in
table for 'concat']])
end
end
end
return concated or ""
end
function table.condense(tab,rewrite)
--this function condenses a tables numerical keys into the lowest it can.
--note, if rewrite is false, it will just return the condensed form. It will not rewrite the table.
--initiation of variables
if type(rewrite) ~="boolean" then rewrite = true end
local condensing = {}
assert(type(tab) == "table",
"Bad item to 'condense'. (table expected, got "..type(tab)..")")
--part to get all the numeric pairs off.
for key,value in pairs(tab) do
if type(key)=="number" then
condensing[#condensing+1]=tab[key]
if rewrite then tab[key]=nil end
end
end
--part to stick them back in.
if rewrite then
for i=1,#condensing do
tab[i]=condensing[i]
end
else
return condensing
end
end
A small function to test condense and concat:
function testIt()
stuff = {}
stuff[1]="3"
stuff[4]="hi"
stuff[6]=10
echo("NEW CONCAT!")
echo(table.concat(stuff))
echo("\nBefore Condense")
for i,x in pairs(stuff) do
echo("\n"..i.." , "..x)
end
table.condense(stuff)
echo("\nAfter Condense!")
for i,x in ipairs(stuff) do
echo("\n"..i.." , "..x)
end
end
the old table.concat would display: '3'
The new table.concat would display: '3hi10'