Подтвердить что ты не робот

Как отформатировать число 1000 как "1 000",

Мне нужен способ форматирования чисел. Я сохранил некоторые цифры в моей таблице DB, например. 12500 и хотели бы напечатать их в этом формате 12 500 (так что есть пробел каждые 3 цифры). Есть ли элегантный способ сделать это?

4b9b3361

Ответ 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"

Ответ 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

Я знаю, что это не в каком-то определенном смысле, но, надеюсь, вы получите эту идею.

Дэвид