Мне нужен способ форматирования чисел. Я сохранил некоторые цифры в моей таблице DB, например. 12500
и хотели бы напечатать их в этом формате 12 500
(так что есть пробел каждые 3 цифры). Есть ли элегантный способ сделать это?
Как отформатировать число 1000 как "1 000",
Ответ 1
см. ниже: http://www.justskins.com/forums/format-number-with-comma-37369.html
нет встроенного в него способа (если вы не используете Rails, ActiveSupport имеет методы для этого), но вы можете использовать Regex, например
formatted_n = n.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
Ответ 2
Activesupport использует это регулярное выражение (и не обратное обратное).
10000000.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1 ") #=> "10 000 000"
Ответ 3
Официальный документ предлагает три разных способа:
1) Использование lookbehind и lookahead (требуется oniguruma)
12500.to_s.gsub(/(?<=\d)(?=(?:\d{3})+\z)/, ' ')
# => "12 500"
2) Использование только lookahead. Идентичность ответа steenslag.
3) Использование ни lookahead, ни lookbehind
s = 12500.to_s
nil while s.sub!(/(.*\d)(\d{3})/, '\1 \2')
s # => "12 500"
Ответ 4
Здесь другой метод, который достаточно чист и прост, если вы имеете дело с целыми числами:
number.to_s.reverse.scan(/\d{1,3}/).join(",").reverse
number #=> 12345678
.to_s #=> "12345678"
.reverse #=> "87654321"
.scan(/\d{1,3}/) #=> ["876","543","21"]
.join(",") #=> "876,543,21"
.reverse #=> "12,345,678"
Отлично работает для целых чисел. Конечно, этот конкретный пример будет разделять число запятыми, но переключение на пробелы или любой другой разделитель так же просто, как замена параметра в методе join
.
Ответ 5
Итак, это довольно сумасшедший и хакерский, но он выполняет свою работу...
12500.to_s.split("").reverse.each_slice(3).map {|y| y.join("").reverse}.reverse.join(" ")
=> "12 500"
.to_s: convert to string
.split(""): split into separate digits
.reverse: reverse order
.each_slice(3): peel of each three digits (working from back end due to reverse)
.map {|y| y.join("").reverse}: map into an array for each three digits - join back together with no delimiter and reverse order back to original
.reverse: reverse order of mapped array
.join(" "): join mapped array back together with space delimiter
Ответ 6
Другой способ:
12500.to_s.reverse().split(//).inject() {|x,i| (x.gsub(/ /,"").length % 3 == 0 ) ? x + " " + i : x + i}.reverse()
Вы всегда можете открыть класс Fixnum и добавить его для удобства:
module FormatNums
def spaceify
self.to_s.reverse().split(//).inject() {|x,i| (x.gsub(/ /,"").length % 3 == 0 ) ? x + " " + i : x + i}.reverse()
end
end
class Fixnum
include FormatNums
end
12500.spaceify # => "12 500"
Ответ 7
очень просто:
number_with_delimiter(12500, delimiter: " ")
см. http://apidock.com/rails/ActionView/Helpers/NumberHelper/number_with_delimiter
Ответ 8
Все, кроме одного из ответов, используют n.to_s
. @MrMorphe не делает, но он создает массив, который должен быть join
ed. Здесь не используется Fixnum # to_s, а Array # join.
def separate(n,c=' ')
m = n
str = ''
loop do
m,r = m.divmod(1000)
return str.insert(0,"#{r}") if m.zero?
str.insert(0,"#{c}#{"%03d" % r}")
end
end
separate(1) #=> "1"
separate(12) #=> "12"
separate(123) #=> "123"
separate(1234) #=> "1 234"
separate(12045) #=> "12 045"
separate(123456) #=> "123 456"
separate(1234000) #=> "1 234 000"
Хммм. Этот столбец справа наклоняется?
Другой способ, который использует to_s
, но не join
:
def separate(n, c=' ')
str = n.to_s
sz = str.size
(3...sz).step(3) { |i| str.insert(sz-i, c) }
str
end
Ответ 9
Это старый, но самый быстрый и элегантный способ, который я мог бы найти, это:
def r_delim(s, e)
(a = e%1000) > 0 ? r_delim(s, e/1000) : return; s << a
end
r_delim([], 1234567).join(',')
Я попытаюсь добавить контрольные точки в какой-то момент.
Ответ 10
Другой способ:
Здесь "разделитель ' '
(пробел), вы можете указать ','
для преобразования денег".
number.to_s.reverse.gsub(%r{([0-9]{3}(?=([0-9])))}, "\\1#{delimiter}").reverse
Ответ 11
Я просто наткнулся на эту тему, ища способ форматировать значение как валюту США. Я предложил несколько иной подход к предлагаемым решениям регулярных выражений:
amt = 1234567890.12
f_amt = format("$%.2f",amt)
i = f_amt.index(".")
while i > 4
f_amt[i-3]=","+f_amt[i-3]
i = f_amt.index(",")
end
f_amt
=> "$1,234,567,890.12"
Это может быть параметризовано для форматирования других валют.
Ответ 12
Я знаю, что это старый вопрос, но.
почему бы просто не использовать подстроку подстановки.
в псевдокоде....
String numberAsString = convertNumberToString(123456);
int numLength = V.length;//determine length of string
String separatedWithSpaces = null;
for(int i=1; i<=numlength; i++){//loop over the number
separatedWithSpaces += numberAsString.getCharacterAtPosition(i);
if(i.mod(3)){//test to see if i when devided by 3 in an integer modulo,
separatedWithSpaces += " ";
}//end if
}//end loop
Я знаю, что это не в каком-то определенном смысле, но, надеюсь, вы получите эту идею.
Дэвид