Có một mẹo đường ray để thêm dấu phẩy cho số lượng lớn?


201

Có cách nào để đường ray in ra một số có dấu phẩy trong đó không?

Ví dụ: nếu tôi có số 54000000.34, tôi có thể chạy <% = number.factor%>, sẽ in ra "54.000.000.34"

cảm ơn!

Câu trả lời:


353

Bạn muốn number_with_delimiterphương pháp. Ví dụ:

<%= number_with_delimiter(@number, :delimiter => ',') %>

Ngoài ra, bạn có thể sử dụng number_with_precisionphương pháp để đảm bảo rằng số luôn được hiển thị với hai vị trí chính xác thập phân:

<%= number_with_precision(@number, :precision => 2, :delimiter => ',') %>

5
@Mo Đó là một phương thức trợ giúp xem. Bạn sẽ có thể sử dụng nó từ một mô-đun bằng cách bao gồm ActionView::Helpers::NumberHelpertrong mô-đun.
John Topley

9
Tôi tin theo mặc định, dấu phân cách là dấu phẩy nên bạn không cần phải vượt qua trong tùy chọn đó trong trường hợp này.
Deekor

3
Bạn nên bỏ dấu phân cách để ngôn ngữ hiện tại có thể quyết định sử dụng cái gì. Điều này cho phép các địa phương sử dụng dấu chấm cho các dấu phân cách được hiển thị đúng thay vì đặt những gì họ sẽ xem là dấu thập phân giữa hàng nghìn. Xem câu trả lời coloradoblue dưới đây.
Kyle Heironimus

1
Cú pháp của Rails 4: <% = number_with_precision (@number, chính xác: 0, dấu phân cách: ',')%>
Choylton B. Higginbottom

2
Coi chừng: number_with_delimiterquá phức tạp và thực sự chậm, với độ sâu của các ngăn xếp cuộc gọi. Nó sử dụng i18nđể có thể định dạng bất kỳ số nào được biết đến bởi các nền văn minh nhân loại và ngoài trái đất (hoặc có thể chỉ để chọn ,hoặc .cho các chữ số thập phân, ngay cả khi bạn chỉ định nó là đối số). Nó phân bổ hàng ngàn đối tượng (vì vậy các mẫu hiệu suất của nó rất phức tạp và khó cấu hình). Cân nhắc chỉ sử dụng regexps nếu bạn không cần hỗ trợ các cách khác nhau để định dạng số tùy theo ngôn ngữ.
đánh cắp

133

Đối với bất cứ ai không sử dụng đường ray:

number.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse

2
Đẹp. Và câu trả lời của bạn có vẻ là tỉ mỉ (chỉ một phần nhỏ của một giây trên một triệu lần lặp) nhanh hơn so với phương pháp này được trình bày ở đây :number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
user664833

bạn có thể giải thích những gì đang xảy ra ở đây? number.to_s.reverse.gsub (/ (\ d {3}) (= \ d) /, '\\ 1,'?) đảo ngược.
Stephen Nguyễn

7
Chắc chắn, nó đảo ngược chuỗi, sau đó thêm dấu phẩy sau bất kỳ chuỗi 3 chữ số nào cũng được theo sau bởi một chữ số khác, sau đó đảo ngược lại.
pguardiario

1
@renosis - Tôi hiểu ý của bạn bây giờ, đây là định dạng tiền tệ. Vì vậy, 2 số thập phân, không phải 7.
pguardiario

2
@pguardiario Cái gì thêm \ cho trong \ 1? không \1đủ sao? Cảm ơn.
butpetwombat

31

Cách trực tiếp để làm điều này, có hoặc không có Rails , là:

require 'active_support/core_ext/numeric/conversions'

12345.to_s(:delimited)      # => "12,345"
12345.6789.to_s(:delimited) # => "12,345.6789"

Để biết thêm tùy chọn, hãy xem Tiện ích mở rộng lõi hỗ trợ hoạt động - Số - Định dạng .


1
Và với sự bao gồm này, bạn có thể sử dụng ActiveSupport::NumberHelper.number_to_delimitedlà tốt. Câu trả lời này xứng đáng nhận được nhiều sự ủng hộ hơn.
Ulysse BN


24

Nếu bạn muốn thêm dấu phẩy ngoài chế độ xem và bạn không muốn bao gồm một số mô-đun, bạn có thể sử dụng phương thức number_to_delrict (phiên bản rails> = 4.02). Ví dụ:

#inside anywhere
ActiveSupport::NumberHelper.number_to_delimited(1000000) # => "1,000,000"

19

Nếu bạn đang làm điều đó rất nhiều nhưng cũng là FYI vì nó không được ngụ ý ở trên, Rails có mặc định hợp lý cho number_with_delimiterphương pháp.

#inside controller or view
number_with_delimiter(2444323.4)
#=> 2,444,323.30

#inside console
helper.number_with_delimiter(233423)
#=> 233,423

Không cần cung cấp giá trị dấu phân cách nếu bạn đang thực hiện theo cách điển hình nhất.


Điều này có thêm lợi ích của việc sử dụng ngôn ngữ hiện tại. Điều này thực sự quan trọng trong các ứng dụng quốc tế vì một số địa phương sử dụng dấu phẩy cho số thập phân và dấu chấm cho hàng nghìn dấu phân cách.
Kyle Heironimus

16

Một cách tốt hơn cho những người không sử dụng đường ray xử lý số thập phân:

parts = number.to_s.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
parts.join('.')

Nếu bạn muốn một dấu phân cách khác, hãy thay đổi ',' cuối cùng trong biểu thức chính quy.

Đối với tiền thưởng, đây là cách regex hoạt động:

  • gsub thay thế mọi thứ khớp với regex bằng tham số thứ hai được truyền cho gsub. Trong trường hợp này là \\1. \\1trở thành \1khi được đánh giá phù hợp với nhóm chụp đầu tiên trong regex. Trong regex đó là (\d).
  • (\d)(?=(\d\d\d)+)phù hợp với một chữ số theo sau bởi 1 hoặc nhiều nhóm 3 chữ số. Nhóm parens đầu tiên là \1nhóm bắt giữ của chúng tôi , nhóm thứ hai sẽ là \2. Nếu chúng ta chỉ để nó ở đó, chúng ta sẽ nhận được: 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456Điều này là do 1234 trận đấu, 2345 trận đấu và 3456 trận đấu nên chúng ta đặt dấu phẩy sau 1, 2 và 3.
  • Bằng cách thêm (?! \ D), chúng tôi sẽ khớp bất kỳ thứ gì có trước số không có trước một chữ số, (\d)(?=(\d\d\d)+(?!\d))nghĩa là khớp với một chữ số theo sau 3 chữ số không theo sau một chữ số. Lý do tại sao điều này hoạt động là gsub sẽ tiếp tục thay thế những thứ phù hợp với chuỗi. Nếu chúng tôi chỉ thay thế trận đấu đầu tiên thì với một số như 123456789, chúng tôi sẽ nhận được 123456,789. Vì 123456,789 vẫn phù hợp với biểu thức chính quy của chúng tôi, chúng tôi nhận được 123,456,789.

Đây là nơi tôi nhận được mã: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

Và đây là nơi tôi đã học về những gì đang diễn ra trong regex đó: http://www.tutorialspoint.com/ruby/ruby_THER_expressions.htmlm


hoạt động như một bùa mê, đặc biệt là trong lang mẫu lỏng:{{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}
Kukunin

2

Một giải pháp khác không sử dụng Helpers: định dạng với 2 chữ số thập phân, sau đó thay thế. bởi,

puts(("%.2f" % 2.5666).gsub('.',','))
>> 2,57

1
Tôi tin rằng câu hỏi là về dấu phẩy cho nhóm chữ số , không phải dấu phẩy như dấu tách thập phân phần / phần thập phân mà câu trả lời của bạn đạt được. (như liên kết wiki giải thích, do sự nhầm lẫn lâu dài, tiêu chuẩn internetional bây giờ khuyên không gian chỉ dành cho chữ số nhóm)
Beni Cherniavsky-Paskin

1

Bạn có thể sử dụng các phương pháp từ ActiveSupport

Ví dụ:

ActiveSupport::NumberHelper::number_to_currency(10000.1234,{precision: 2,unit: ''})


1
  def add_commas(numstring)
    correct_idxs = (1..100).to_a.select{|n| n % 6 == 0}.map{|n| n - 1}
     numstring.reverse.chars.join(",").chars.select.with_index{|x, i| i.even? || correct_idxs.include?(i)}.join.reverse
  end

Đây là cách của tôi trong ruby

Chỉnh sửa bổ sung: Về cơ bản, nó thêm tất cả dấu phẩy vào giữa các số và chỉ chọn những dấu trong đó chỉ mục + 1% 6

Tôi cho rằng dấu phẩy lên tới 100 là ổn nhưng nếu bạn muốn một số siêu dài chỉ cần tạo 100 số cao hơn


0

cú pháp mới

number_with_delimeter(@number, delimeter: ",")

Nếu bạn muốn người dùng phân định tiền để kiếm tiền thì bạn có thể làm

number_to_currency(@number)

này sẽ bổ sung thêm $quá. Nếu bạn đang sử dụng moneyđá quý thì bạn có thể làm

Money.new(@number,"USD").format

Điều này cũng sẽ đặt $.

số_with_d Friiter

tiền ruby

số_to_currency


0

Sau đây thực hiện thủ thuật cho cả dấu phân cách và độ chính xác ( API ref ).

ActiveSupport::NumberHelper.number_to_rounded(1234.532, delimiter: ',', precision: 1) 

(hoặc từ lượt xem chỉ number_to_rounded, không cần hậu tố)

HTH


-1

cho người dùng javascript

function numberWithDelimiter(value) {
    return (value+"").split("").reverse().join("").replace(/(\d{3})(?=\d)/g, '$1,').split("").reverse().join("")
}

:)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.