Büyük sayılara virgül eklemenin bir yolu var mı?


201

İçinde virgül bulunan bir sayıyı yazdırmanın bir yolu var mı?

Örneğin, 54000000.34'lük bir numaram varsa, "% 54.000.000.34" yazdıracak <% = number.function%> çalıştırabilirim.

Teşekkürler!

Yanıtlar:


353

number_with_delimiterYöntemi istiyorsunuz . Örneğin:

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

Alternatif olarak, number_with_precisionsayının her zaman iki ondalık hassasiyetle görüntülenmesini sağlamak için yöntemi kullanabilirsiniz :

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

5
@Mo Bu bir görünüm yardımcı yöntemidir. Modül ActionView::Helpers::NumberHelperiçine dahil ederek bir modülden kullanabilmeniz gerekir .
John Topley

9
Varsayılan olarak sınırlayıcının virgül olduğuna inanıyorum, bu durumda bu seçeneği geçmeniz gerekmeyecek.
Deekor

3
Geçerli yerel ayarın ne kullanacağına karar verebilmesi için sınırlayıcıyı kapalı bırakmalısınız. Bu, sınırlayıcılar için dönemleri kullanan yerel ayarların, binler arasında ondalık bir nokta olarak değerlendireceklerini koymak yerine düzgün görüntülenmesini sağlar. Aşağıdaki coloradoblue cevabına bakınız.
Kyle Heironimus

1
Raylar 4 sözdizimi: <% = number_with_precision (@ sayı, hassasiyet: 0, sınırlayıcı: ',')%>
Choylton B. Higginbottom 23:15

2
Dikkat: number_with_delimiterAşırı karmaşık ve gerçekten yavaş, muazzam çağrı yığınları derinliği ile. i18nİnsanlık ve dünya dışı medeniyetler tarafından bilinen herhangi bir sayıyı biçimlendirmek için kullanır (veya bağımsız değişken olarak belirtseniz bile, yalnızca ondalık basamaklar için ,veya birini seçmek .için). Binlerce nesne tahsis eder (bu nedenle performans kalıpları karmaşıktır ve profili zor). Yerel ayara bağlı olarak sayıları biçimlendirmenin farklı yollarını desteklemeniz gerekmiyorsa, yalnızca normal ifadeleri kullanmayı düşünün.
kolen

133

Ray kullanmayanlar için:

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

2
Güzel. Ve cevap olarak görünüyor inceden (bir milyon tekrarlamalar üzerinde bir saniyenin yalnızca bir kısmını) hızlı yaklaşımından daha sundu burada :number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
user664833

burada neler olduğunu açıklayabilir misiniz? number.to_s.reverse.gsub (/ (\ d {3}) (? = \ d) /, '\\ 1,'). ters
Stephen Nguyen

7
Elbette, dizeyi tersine çevirir, ardından 3 haneli herhangi bir diziden sonra bir virgül ekler, bunu da başka bir basamak izler, sonra geri döndürür.
pguardiario

1
@renosis - Şimdi ne demek istediğini anlıyorum, bu para birimini biçimlendirmek için. Yani 2 ondalık sayı, 7 değil.
pguardiario

2
@pguardiario \\ 1'deki ekstra \ ne için? \1yeterli değil mi? Teşekkürler.
butterywombat



24

Görünümlerin dışında virgül eklemek istiyorsanız ve bazı modüller eklemek istemiyorsanız, number_to_delimited yöntemini kullanabilirsiniz (rails sürümü> = 4.02). Örneğin:

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

19

Çok fazla değil, aynı zamanda FYI'yi de yukarıdakiler tarafından ima edilmediğinden, Rails'in number_with_delimiteryöntem için varsayılan varsayılanları vardır .

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

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

En tipik şekilde yapıyorsanız sınırlayıcı değerini sağlamanıza gerek yoktur.


Bunun, geçerli yerel ayarı kullanma avantajı vardır. Bu, bazı yerel ayarlarda ondalık virgül ve binlerce ayırıcı için virgül kullandığından, uluslararası uygulamalarda gerçekten önemlidir.
Kyle Heironimus

16

Ondalık basamakları işleyen raylar kullanmayanlar için daha iyi bir yol:

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

Farklı bir sınırlayıcı istiyorsanız, normal ifadedeki son ',' işaretini değiştirin.

Bonus için, normal ifade şu şekilde çalışır:

  • gsub, normal ifadeyle eşleşen her şeyi gsub'a iletilen ikinci parametre ile değiştirir. Bu durumda \\1.\\1\1normal ifadedeki ilk yakalama grubuyla eşleşen değerlendirildiğinde olur . Bu normal ifadede(\d) .
  • (\d)(?=(\d\d\d)+)bir rakam ve ardından 1 veya daha fazla 3 basamaklı grup eşleşiyor. İlk parens seti bizim\1 yakalama grubumuz, ikincisi olurdu \2. Eğer sadece onu bırakacak olsaydık, 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456bunun nedeni 1234 maç, 2345 maç ve 3456 maç olduğu için 1, 2 ve 3'ten sonra virgül koyduk.
  • (?! \ D) ekleyerek, bir rakamdan önce gelmeyen herhangi bir şeyle eşleşiriz. (\d)(?=(\d\d\d)+(?!\d)) bir rakamın ardından bir rakamın ardından gelen 3 rakamın eşleşmesi anlamına gelir. Bunun çalışmasının nedeni, gsub'ın dizeyle eşleşen şeylerin yerini almaya devam etmesidir. Sadece ilk maçı değiştirecek olsaydık, 123456789 gibi bir sayı için 123456,789 alırdık. 123456.789 hala normal ifademizle eşleştiğinden 123.456.789 elde ediyoruz.

İşte kodu aldım: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

Ve işte bu regex'te neler olduğunu öğrendim: http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm


Özellikle Liquid template {{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}
lang'de

2

Helpers kullanmayan başka bir çözüm: 2 ondalık basamakla biçimlendirin ve değiştirin. tarafından ,

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

1
Sorunun, yanıtın ulaştığı intergral parça / kesir kısmı ondalık ayırıcı olarak virgül değil, basamak gruplaması için virgülle ilgili olduğuna inanıyorum . (bu wiki bağlantısının açıkladığı gibi, uzun süredir devam eden karışıklık nedeniyle, internet standartları artık sadece rakam gruplaması için alanlar önermektedir)
Beni Cherniavsky-Paskin

1

Şu yöntemleri kullanabilirsiniz: ActiveSupport

Örneğin:

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

Bu yakutta benim yolumdu

Ekleme düzenleme: Temelde sayılar arasındaki tüm virgülleri ekler ve sadece endeksin +% 1% 6

100'e kadar virgülün iyi olduğunu düşündüm ama süper uzun bir sayı istiyorsanız sadece 100 daha yüksek bir sayı yapın


0

yeni sözdizimi

number_with_delimeter(@number, delimeter: ",")

Para için kullanıcı sınırlayıcıyı istiyorsanız, bunu yapabilirsiniz

number_to_currency(@number)

bu da eklenecektir $. moneyGem kullanıyorsanız o zaman yapabilirsiniz

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

Bu da koyacaktır $.

number_with_delimiter

yakut para

number_to_currency


0

Aşağıdakiler hem sınırlayıcı hem de kesinlik ( API ref ) için hile yapar .

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

(veya yalnızca görüşlere göre number_to_rounded, son eke gerek yoktur)

HTH


-1

javascript kullanıcıları için

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

:)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.