i\'d like to format a number to look as follows \"1,234\" or \"1,234,432\" or \"123,456,789\", you get the idea. I tried doing this as follows;
function ref
Well, let's take this from the top down. First of all, it's failing because you've got a reference error:
...
for k = 1, 3 do
newint = string.sub(mystring, -k*v) -- What is 'mystring'?
end
...
Most likely you want i
to be there, not mystring
.
Second, while replacing mystring
with i
will fix the errors, it still won't work correctly.
> =reformatint(100)
,100
> =reformatint(1)
,000
That's obviously not right. It seems like what you're trying to do is go through the string, and build up the new string with the commas added. But there are a couple of problems...
function reformatint(i)
local length = string.len(i)
for v = 1, math.floor(length/3) do
for k = 1, 3 do -- What is this inner loop for?
newint = string.sub(mystring, -k*v) -- This chops off the end of
-- your string only
end
newint = ','..newint -- This will make your result have a ',' at
-- the beginning, no matter what
end
return newint
end
With some rework, you can get a function that work.
function reformatint(integer)
for i = 1, math.floor((string.len(integer)-1) / 3) do
integer = string.sub(integer, 1, -3*i-i) ..
',' ..
string.sub(integer, -3*i-i+1)
end
return integer
end
The function above seems to work correctly. However, it's fairly convoluted... Might want to make it more readable.
As a side note, a quick google search finds a function that has already been made for this:
function comma_value(amount)
local formatted = amount
while true do
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
if (k==0) then
break
end
end
return formatted
end
I remember discussing about this in the LÖVE forums ... let me look for it...
Found it!
This will work with positive integers:
function reformatInt(i)
return tostring(i):reverse():gsub("%d%d%d", "%1,"):reverse():gsub("^,", "")
end
On the link above you may read details about implementation.
Here's a function that takes negative numbers, and fractional parts into account:
function format_int(number)
local i, j, minus, int, fraction = tostring(number):find('([-]?)(%d+)([.]?%d*)')
-- reverse the int-string and append a comma to all blocks of 3 digits
int = int:reverse():gsub("(%d%d%d)", "%1,")
-- reverse the int-string back remove an optional comma and put the
-- optional minus and fractional part back
return minus .. int:reverse():gsub("^,", "") .. fraction
end
assert(format_int(1234) == '1,234')
assert(format_int(1234567) == '1,234,567')
assert(format_int(123456789) == '123,456,789')
assert(format_int(123456789.1234) == '123,456,789.1234')
assert(format_int(-123456789.) == '-123,456,789')
assert(format_int(-123456789.1234) == '-123,456,789.1234')
assert(format_int('-123456789.1234') == '-123,456,789.1234')
print('All tests passed!')
You can do without loops:
function numWithCommas(n)
return tostring(math.floor(n)):reverse():gsub("(%d%d%d)","%1,")
:gsub(",(%-?)$","%1"):reverse()
end
assert(numWithCommas(100000) == "100,000")
assert(numWithCommas(100) == "100")
assert(numWithCommas(-100000) == "-100,000")
assert(numWithCommas(10000000) == "10,000,000")
assert(numWithCommas(10000000.00) == "10,000,000")
The second gsub is needed to avoid -,100 being generated.