2012-06-12 26 views
6

me gustaría formatear un número para que se vea como "1,234" o "1,234,432" o "123,456,789", se entiende. Intenté hacer esto de la siguiente manera;Lua - Formato entero

function reformatint(i) 
    local length = string.len(i) 
    for v = 1, math.floor(length/3) do 
     for k = 1, 3 do 
      newint = string.sub(mystring, -k*v) 
     end 
     newint = ','..newint 
    end 
    return newint 
end 

Como se puede ver que tengo un intento fallido, el problema es que no puedo trabajar en lo que es la culpa como el programa estoy funcionando en este, se niega a publicar un error de nuevo a mí.

Respuesta

3

Bueno, tomemos esto de arriba hacia abajo. En primer lugar, está fallando debido a que tienes un error de referencia:

... 
     for k = 1, 3 do 
      newint = string.sub(mystring, -k*v) -- What is 'mystring'? 
     end 
    ... 

más probable es que quieren i para estar allí, no mystring.

En segundo lugar, al reemplazar mystring con i corregirá los errores, todavía no funcionará correctamente.

> =reformatint(100) 
,100 
> =reformatint(1) 
,000 

Eso obviamente no es correcto. Parece que lo que estás tratando de hacer es ir a través de la cadena y construir la nueva cadena con las comas añadidas. Pero hay un par de problemas ...

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 

Con algunas repeticiones, puede obtener una función que funcione.

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 

La función anterior parece funcionar correctamente. Sin embargo, es bastante intrincado ... Podría querer que sea más legible.

Como nota al margen, una quick google search encuentra una función que ya se ha hecho para esto:

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

uff, arranqué el bit que contiene mystring de una página web, obviamente fui lo suficientemente tonto como para olvidarme de cambiar eso. como resultado, mis búsquedas de google fueron terriblemente incorrectas. Me gustaría darle las gracias, y voy a ver mucho más profundo cómo funciona string.sub(). Espero que mi estupidez hasta ahora al menos me permita aprender algo. – Hultin

+1

@Hultin: No hay necesidad de menospreciarse a sí mismo; todos cometemos errores, y a veces son tontos. Así es como aprendemos. Y sí, entendiendo 'cadena.sub() 'es un esfuerzo que vale la pena - en realidad es un poco diferente que las funciones de subcadenas en otros idiomas. Además, bienvenido a StackOverflow! – voithos

1

Puede prescindir de bucles:

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") 

Se necesita el segundo gsub a evitar - , 100 siendo generado.

+1

Buen intento, pero te pierdes números de 3, 6, etc. Puedes solucionar esto usando 'gsub (", (% -?) $ ","% 1 ")' para la última llamada 'gsub'. Esto reemplaza un '', '' o ',' posterior con la versión sin la coma. – jpjacobs

+0

de hecho. fijo. gracias @jpjacobs. –

10

Aquí es una función que toma los números negativos, y las partes fraccionarias en cuenta:

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!') 
1

Recuerdo discutir sobre esto en el LÖVE forums ... que lo vea por ello ...

Found it!

Esto funciona con números enteros positivos:

function reformatInt(i) 
    return tostring(i):reverse():gsub("%d%d%d", "%1,"):reverse():gsub("^,", "") 
end 

En el enlace de arriba se puede leer detalles acerca de la implementación.