Чи є хитрість рейки до додавання коми до великої кількості?


201

Чи є спосіб, щоб рейки роздрукували номер із комами?

Наприклад, якщо у мене є номер 54000000.34, я можу запустити <% = number.function%>, який видав би "54,000,000.34"

Дякую!

Відповіді:


353

Ви хочете number_with_delimiterметод. Наприклад:

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

Крім того, ви можете використовувати number_with_precisionметод, щоб переконатися, що число завжди відображається з двома десятковими знаками точності:

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

5
@Mo Це метод помічника перегляду. Ви повинні мати можливість використовувати його з модуля, включивши його ActionView::Helpers::NumberHelperв модуль.
Джон Топлі

9
Я вважаю, що за замовчуванням роздільник є комою, тому в цьому випадку вам не потрібно буде передавати цей параметр.
Дікор

3
Ви повинні залишити роздільник, щоб поточний локал міг вирішити, що використовувати. Це дозволяє правильно відображати локалі, які використовують періоди для роздільників, а не ставити те, що вони вважатимуть десятковою точкою між тисячами. Дивіться відповідь coloradoblue нижче.
Кайл Гейронімус

1
Синтаксис Rails 4: <% = number_with_precision (@ число, точність: 0, роздільник: ',')%>
Choylton B. Higginbottom,

2
Остерігайтеся: number_with_delimiterнадмірно складний і справді повільний, з величезною глибиною стеку викликів. Він i18nмає змогу відформатувати будь-які числа, відомі людству та позаземним цивілізаціям (а може, просто вибрати будь-яку ,чи .десяткову цифру, навіть якщо ви вказали це як аргумент). Він виділяє тисячі об'єктів (тому його ефективність є складною і важкою для профілювання). Подумайте просто використовувати регулярні вирази, якщо вам не потрібно підтримувати різні способи форматування чисел залежно від мови.
колен

133

Для тих, хто не використовує рейки:

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

2
Приємно. І ваша відповідь здається щомісяця (лише частку секунди понад мільйон ітерацій) швидше, ніж підхід, представлений тут :number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
user664833

ви можете пояснити, що тут відбувається? number.to_s.reverse.gsub (/ (\ d {3}) (? = \ d) /, '\\ 1,'). Зворотний
Стівен Нгуен

7
Звичайно, він обертає рядок, потім додає кому після будь-якої послідовності з 3 цифр, за якою також слідує інша цифра, а потім повертає її назад.
pguardiario

1
@renosis - я бачу, що ви маєте на увазі зараз, це для форматування валюти. Отже, 2 десяткові дроби, а не 7.
pguardiario

2
@pguardiario Що додаткового \ у \\ 1? НЕ \1досить? Дякую.
butterywombat

31

Прямий спосіб зробити це з рейками або без них:

require 'active_support/core_ext/numeric/conversions'

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

Для отримання додаткових опцій див. Розділ Розширення основних служб підтримки - Числове - Форматування .


1
І з цим включенням ви також можете використовувати ActiveSupport::NumberHelper.number_to_delimited. Ця відповідь заслуговує на набагато більше результатів.
Уліссе БН


24

Якщо ви хочете додати коми поза переглядами, і ви не хочете включати деякі модулі, ви можете скористатися методом number_to_delimited (рейкова версія> = 4.02). Наприклад:

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

19

Якщо ви робите це багато, але і FYI, оскільки це не має на увазі вищезазначене, Rails має обґрунтовані параметри за замовчуванням number_with_delimiter.

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

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

Не потрібно вказувати значення роздільника, якщо ви робите це найбільш типовим способом.


Це має додаткову перевагу використання поточного локалу. Це дійсно важливо для міжнародних додатків, оскільки деякі локалі використовують коми через десятковий знак, а періодичний - для роздільника тисяч.
Кайл Гейронімус

16

Кращий спосіб для тих, хто не використовує рейки, що обробляє десятичні знаки:

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

Якщо ви хочете інший роздільник, змініть останнє "," в регулярному виразі.

Для бонусу це працює регулярний вираз:

  • gsub замінює все, що відповідає регулярному вираженню, другим параметром, переданим gsub. У цьому випадку це \\1. \\1стає, \1коли оцінюється, яка відповідає першій групі захоплення в регулярному виразі. У цьому регулярному вираженні, що є (\d).
  • (\d)(?=(\d\d\d)+)- це відповідність цифри з 1 або більше групами з 3 цифр. Перший набір паронів - це наша \1група захоплення, другий - це \2. Якби ми просто залишили це, ми отримали: 123456.gsub!(/(\d)(?=(\d\d\d)+)/, "\\1,") #=> 1,2,3,456Це тому, що 1234 матчі, 2345 матчів та 3456 матчів, тому ми ставимо кому після 1, 2 та 3.
  • Додаючи (?! \ D), ми узгоджуємо все, що сталося до цього, що не передує цифрі, тому (\d)(?=(\d\d\d)+(?!\d))означає відповідність цифрі, а потім 3 цифри, а не цифру. Причина, чому це працює, полягає в тому, що gsub продовжує замінювати речі, що відповідають рядку. Якби ми тільки збиралися замінити перший матч, тоді для такого числа, як 123456789, ми отримали 123456,789. Оскільки 123456,789 як і раніше відповідає нашому регексу, ми отримуємо 123,456,789.

Ось, де я отримав код: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/number_helper.rb#L298-L300

І ось, де я дізнався про те, що відбувається в цьому регулярному виразі: http://www.tutorialspoint.com/ruby/ruby_regular_expressions.htm


працює як шарм, особливо у рідкому шаблоні шаблонів:{{ value | round | replace: "(\d)(?=(\d\d\d)+(?!\d))", "$1," | prepend: "$" }}
Кукунін

2

Ще одне рішення, яке не використовує Helpers: відформатуйте 2 знаки після коми, а потім замініть. від,

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

1
Я вважаю, що питання стосувалося коми для угруповання цифр , а не кома як розділовий розділовий розділовий розділ / частка дробу, якого досягає ваша відповідь. (Як пояснює , що посилання вікі з - за давньою плутанини, Internetional стандарти рекомендують простору тільки для груп розрядів)
Бені Чернявський-Паскін

1

Ви можете використовувати методи від ActiveSupport

Наприклад:

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

Це був мій шлях в рубіні

Редагування доповнень: В основному він додає всі коми між числами і вибирає лише ті, де індекс + 1% 6

Я вважав, що коси до 100 - це добре, але якщо ви хочете супер довге число, просто зробіть 100 більшим числом


0

новий синтаксис

number_with_delimeter(@number, delimeter: ",")

Якщо ви хочете користуватися деліметром користувача на гроші, то можете це зробити

number_to_currency(@number)

це також додасть $. Якщо ви використовуєте moneyдорогоцінний камінь, то можете зробити

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

Це також поставить $.

число_з_делімітером

рубінові гроші

число_то_валюти


0

Далі робимо хитрість як для роздільника, так і для точності ( API ref ).

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

(або з переглядів просто number_to_rounded, суфікс не потребує)

HTH


-1

для javascript людей

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

:)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.