2012-06-12 9 views
6

Я хотел бы отформатировать число, выглядящее следующим образом: «1,234» или «1,234,432» или «123,456,789», вы получаете идею. Я пробовал делать это следующим образом;Lua - целое целое число

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 

Как вы можете видеть, у меня есть неудавшаяся попытка, проблема, я не могу работать, что по вине как программа я бег это, отказывается оставить ошибку ко мне.

ответ

3

Хорошо, давайте возьмем это сверху вниз. Прежде всего, это недостаток, потому что у вас есть ссылочный ошибка:

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

Скорее всего, вы хотите i быть там, а не mystring.

Во-вторых, при замене mystring с помощью i будут исправлены ошибки, они все равно будут работать неправильно.

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

Это, очевидно, не так. Кажется, что вы пытаетесь сделать, это пройти через строку и создать новую строку с добавленной запятой. Но есть пара проблем ...

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 

С некоторой доработкой вы можете получить функцию, которая работает.

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 

Функция, как представляется, работает правильно. Тем не менее, он довольно запутанный ... Мог бы сделать его более читаемым.

В качестве примечания, quick google search находит функцию, которая уже была сделана для этого:

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, я разорвал бит, содержащий мистик с веб-страницы, очевидно, я был достаточно глупым, чтобы забыть поменять это. , как оказалось, мои поисковые запросы Google были ужасно неправильными. Я хотел бы поблагодарить вас, и я рассмотрю гораздо глубже, как работает string.sub(). Надеюсь, что до сих пор моя глупость позволит мне чему-то научиться. – Hultin

+1

@ Hultin: Не нужно смотреть на себя сверху вниз - мы все совершаем ошибки, а иногда они глупые. Так мы учимся. И да, понимая 'string.sub() 'является стоящим делом - он фактически немного отличается от подстрочных функций на других языках. Кроме того, добро пожаловать в StackOverflow! – voithos

1

Вы можете обойтись без петель:

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

Второй GSUB необходимо избегать - , 100.

+1

Хорошая попытка, но вы пропустите числа длиной 3, 6 и т. Д. Вы можете обойти это, используя 'gsub (", (% -?) $ ","% 1 ")' для последнего вызова 'gsub'. Это заменяет конечную версию '-,' или ',' версией без запятой. – jpjacobs

+0

действительно. исправлено. спасибо @jpjacobs. –

10

Вот функция, которая принимает отрицательные числа и дробные части во внимание:

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

Я помню обсуждение об этом в LÖVE forums ... дайте мне взглянуть на него ...

Found it!

Это будет работать с положительными целыми числами:

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

На ссылке выше вы можете прочитать подробную информацию о реализации.

Смежные вопросы