2012-06-12 47 views
6

Tôi muốn định dạng một số để xem như sau "1,234" hoặc "1,234,432" hoặc "123,456,789", bạn sẽ có ý tưởng. Tôi đã thử làm như sau;Lua - Định dạng số nguyên

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 

Như bạn thấy tôi gặp sự cố không thành công, vấn đề là tôi không thể tìm ra lỗi của chương trình mà tôi đang chạy, từ chối đăng lỗi lại cho tôi.

Trả lời

3

Vâng, hãy thực hiện việc này từ trên xuống dưới. Trước hết, đó là thất bại vì bạn đã có một lỗi tham khảo:

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

Nhiều khả năng bạn muốn i để có mặt ở đó, không mystring.

Thứ hai, trong khi thay thế mystring bằng i sẽ sửa lỗi, nó vẫn không hoạt động chính xác.

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

Điều đó rõ ràng là không đúng. Nó có vẻ như những gì bạn đang cố gắng làm là đi qua chuỗi, và xây dựng chuỗi mới với dấu phẩy được thêm vào. Nhưng có một vài vấn đề ...

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 

Với một số làm lại, bạn có thể có một chức năng hoạt động.

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 

Chức năng ở trên dường như hoạt động chính xác. Tuy nhiên, nó khá phức tạp ... Có thể muốn làm cho nó dễ đọc hơn.

Là một mặt lưu ý, một quick google search tìm thấy một chức năng đó đã được thực hiện cho việc này:

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, tôi đã tách một chút có chứa bí ẩn từ một trang web, rõ ràng là tôi đủ ngớ ngẩn để quên hoán đổi điều đó. khi nó bật ra, tìm kiếm google của tôi là khủng khiếp không chính xác. Tôi muốn cảm ơn bạn và tôi sẽ xem xét kỹ hơn cách string.sub() hoạt động. Tôi hy vọng rằng sự ngu xuẩn của tôi đến nay sẽ khiến tôi học được điều gì đó. – Hultin

+1

@Hultin: Không cần phải nhìn xuống chính mình - tất cả chúng ta đều phạm sai lầm, và đôi khi họ là những người ngớ ngẩn. Đó là cách chúng ta học. Và có, hiểu 'chuỗi.sub() 'là một nỗ lực đáng giá - nó thực sự hơi khác với các hàm chuỗi con trong các ngôn ngữ khác. Ngoài ra, chào mừng bạn đến với StackOverflow! – voithos

1

Bạn có thể làm mà không có vòng:

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

Các gsub thứ hai là cần thiết để tránh - , 100 đang được tạo.

+1

Thử tốt, nhưng bạn bỏ lỡ số lượng chiều dài 3, 6, vv Bạn có thể sử dụng 'gsub (", (% -?) $ ","% 1 ")' cho lệnh gọi 'gsub' cuối cùng. Điều này thay thế một dấu "-,' hoặc ',' với phiên bản không có dấu phẩy. – jpjacobs

+0

thực sự. đã sửa. cảm ơn @jpjacobs. –

10

Dưới đây là một chức năng mà có số âm, và các bộ phận phân đoạn vào tài khoản:

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

Tôi nhớ thảo luận về vấn đề này trong LÖVE forums ... hãy để tôi tìm kiếm nó ...

Found it!

này sẽ làm việc với số nguyên dương:

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

Trên diễn đàn bạn có thể đọc thông tin chi tiết về việc thực hiện.

Các vấn đề liên quan