Lua - Format integer

后端 未结 4 1406
天涯浪人
天涯浪人 2020-12-11 18:27

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         


        
相关标签:
4条回答
  • 2020-12-11 18:53

    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
    
    0 讨论(0)
  • 2020-12-11 18:59

    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.

    0 讨论(0)
  • 2020-12-11 19:05

    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!')
    
    0 讨论(0)
  • 2020-12-11 19:05

    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.

    0 讨论(0)
提交回复
热议问题