Apakah ada trik rel untuk menambahkan koma ke jumlah besar?


201

Apakah ada cara agar rel mencetak nomor dengan koma?

Misalnya, jika saya memiliki nomor 54000000.34, saya dapat menjalankan <% = number.function%>, yang akan mencetak "54.000.000.000,34"

Terima kasih!

Jawaban:


353

Anda menginginkan number_with_delimitermetodenya. Sebagai contoh:

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

Atau, Anda dapat menggunakan number_with_precisionmetode ini untuk memastikan bahwa angka selalu ditampilkan dengan dua tempat desimal presisi:

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

5
@ Mo Ini adalah metode view helper. Anda harus dapat menggunakannya dari modul dengan memasukkannya ke ActionView::Helpers::NumberHelperdalam modul.
John Topley

9
Saya percaya secara default pembatas adalah koma sehingga Anda tidak perlu memasukkan opsi itu dalam kasus ini.
Deekor

3
Anda harus mematikan pembatas agar lokal saat ini dapat memutuskan apa yang akan digunakan. Ini memungkinkan lokal yang menggunakan periode untuk pembatas untuk ditampilkan dengan benar daripada menempatkan apa yang mereka anggap sebagai titik desimal antara ribuan. Lihat jawaban coloradoblue di bawah ini.
Kyle Heironimus

1
Sintaks Rails 4: <% = number_with_precision (@number, presisi: 0, pembatas: ',')%>
Choylton B. Higginbottom

2
Waspadalah: number_with_delimiterterlalu rumit dan sangat lambat, dengan kedalaman tumpukan panggilan yang sangat besar. Ini digunakan i18nuntuk dapat memformat angka yang dikenal manusia dan peradaban ekstraterestrial (atau mungkin hanya untuk memilih salah satu ,atau .untuk angka desimal, bahkan jika Anda menetapkannya sebagai argumen). Ini mengalokasikan ribuan objek (jadi pola kinerjanya kompleks dan sulit diprofilkan). Pertimbangkan hanya menggunakan regexps jika Anda tidak perlu mendukung berbagai cara untuk memformat angka tergantung pada lokal.
kolen

133

Bagi siapa pun yang tidak menggunakan rel:

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

2
Bagus. Dan jawaban Anda tampaknya sangat kecil (hanya sepersekian detik dari satu juta iterasi) lebih cepat daripada pendekatan yang disajikan di sini :number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
user664833

dapatkah Anda menjelaskan apa yang sedang terjadi di sini? number.to_s.reverse.gsub (/ (\ d {3}) (? = \ d) /, '\\ 1,') terbalik
Stephen Nguyen

7
Tentu, itu membalikkan string, kemudian menambahkan koma setelah urutan 3 digit yang juga diikuti oleh digit lain, lalu membalikkannya kembali.
pguardiario

1
@renosis - Saya mengerti maksud Anda sekarang, ini untuk memformat mata uang. Jadi 2 desimal, bukan 7.
pguardiario

2
@pguardiario Untuk apa \ \ tambahan di \\ 1? tidak \1cukup? Terima kasih.
butterywombat



24

Jika Anda ingin menambahkan koma di luar tampilan dan Anda tidak ingin menyertakan beberapa modul, Anda dapat menggunakan metode number_to_delimited (versi rel> = 4.02). Sebagai contoh:

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

19

Jika Anda sering melakukannya tetapi juga FYI karena tidak tersirat di atas, Rails memiliki default yang masuk akal untuk number_with_delimitermetode ini.

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

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

Tidak perlu memberikan nilai pembatas jika Anda melakukannya dengan cara yang paling khas.


Ini memiliki manfaat tambahan menggunakan lokal saat ini. Ini sangat penting dalam aplikasi internasional karena beberapa lokal menggunakan koma untuk desimal dan titik untuk ribuan pemisah.
Kyle Heironimus

16

Cara yang lebih baik bagi mereka yang tidak menggunakan rel yang menangani desimal:

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

Jika Anda ingin pembatas yang berbeda, ubah ',' terakhir di regex.

Untuk bonus, ini adalah cara kerja regex:

  • gsub menggantikan semua yang cocok dengan regex dengan parameter kedua diteruskan ke gsub. Dalam hal ini adalah \\1. \\1menjadi \1ketika dievaluasi yang cocok dengan kelompok tangkapan pertama di regex. Di regex ini yaitu(\d) .
  • (\d)(?=(\d\d\d)+)cocok dengan digit diikuti oleh 1 atau lebih grup dengan 3 digit. Set parens pertama adalah \1grup tangkap kami , yang kedua adalah \2. Jika kita hanya membiarkannya saja maka kita akan mendapatkan: 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456Ini karena 1234 pertandingan, 2345 pertandingan dan 3456 pertandingan jadi kami menempatkan koma setelah 1, 2, dan 3.
  • Dengan menambahkan (?! \ D) kami mencocokkan apa pun yang datang sebelum yang tidak mendahului digit sehingga (\d)(?=(\d\d\d)+(?!\d))berarti cocok dengan digit diikuti oleh 3 digit yang tidak diikuti oleh digit. Alasan mengapa ini berhasil adalah gsub akan terus mengganti hal-hal yang cocok dengan string. Jika kami hanya akan mengganti pertandingan pertama maka untuk nomor seperti 123456789 kami akan mendapatkan 123456.789. Karena 123456.789 masih cocok dengan regex kami, kami mendapatkan 123.456.789.

Di sinilah saya mendapatkan kode: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

Dan di sinilah saya belajar tentang apa yang terjadi di regex itu: http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm


bekerja seperti pesona, terutama dalam template Cair lang:{{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}
Kukunin

2

Solusi lain yang tidak menggunakan Helpers: format dengan 2 tempat desimal, lalu ganti. oleh ,

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

1
Saya percaya pertanyaannya adalah tentang koma untuk pengelompokan digit , bukan koma sebagai pemisah desimal bagian / fraksi intergral yang jawaban Anda capai. (seperti yang dijelaskan oleh tautan wiki itu, karena kebingungan yang sudah berlangsung lama, standar internet sekarang merekomendasikan ruang hanya untuk pengelompokan digit)
Beni Cherniavsky-Paskin

1

Anda dapat menggunakan metode dari ActiveSupport

Sebagai contoh:

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

Ini jalan saya di ruby

Edit penambahan: Pada dasarnya ia menambahkan semua koma di antara angka-angka dan hanya memilih yang koma dengan indeks + 1% 6

Saya pikir koma hingga 100 baik-baik saja, tetapi jika Anda ingin nomor super panjang, buatlah 100 lebih tinggi


0

sintaks baru

number_with_delimeter(@number, delimeter: ",")

Jika Anda ingin delimeter pengguna untuk uang maka Anda dapat melakukannya

number_to_currency(@number)

ini akan menambah $juga. Jika Anda menggunakan moneypermata maka Anda bisa melakukannya

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

Ini juga akan dimasukkan $.

number_with_delimiter

uang ruby

number_to_currency


0

Berikut ini lakukan trik untuk pembatas dan presisi ( API ref ).

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

(atau dari tampilan saja number_to_rounded, tidak perlu sufiks)

HTH


-1

untuk orang-orang javascript

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

:)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.