Feature #16011
closedDigit grouping
Description
Ruby seems to have no way to format a number with grouped thousands. I see Rails
has an option:
require 'active_support/all'
1234.to_s(:delimited)
However in this case it seems that grouping cannot be combined with say, leading
zeros:
https://github.com/rails/rails/issues/36707
This is quite simple with other languages, for example JavaScript:
(1234).toLocaleString(0, {minimumIntegerDigits: 7});
"0,001,234"
Python:
>>> format(1234, '08,')
'0,001,234'
Go:
package main
import "golang.org/x/text/language"
import "golang.org/x/text/message"
func main() {
message.NewPrinter(language.English).Printf("%07d\n", 1234)
// 0,001,234
}
Updated by znz (Kazuhiro NISHIYAMA) over 5 years ago
- Tracker changed from Bug to Feature
- Backport deleted (
2.5: UNKNOWN, 2.6: UNKNOWN)
Updated by duerst (Martin Dürst) over 5 years ago
Just for the record:
- What to use as thousands separator is locale-dependent. It can be a comma (US), a dot (Germany), an apostrophe (Switzerland), a space (Sweden; usually a narrow-width, non-breaking space), and so on.
- Some locales don't use thousands separators, and the separators don't have to come in regular intervals (e.g. Hindi).
Updated by shyouhei (Shyouhei Urabe) over 5 years ago
- Related to Feature #12447: Integer#digits for extracting digits of place-value notation in any base added
Updated by shyouhei (Shyouhei Urabe) over 5 years ago
class Integer
def delimited(n)
div, mod = n.divmod(3)
return ( \
digits(1000).lazy + [0].cycle \
) . first(div + 1) \
. reverse \
. map {|i| '%03d' % i } \
. join(',') \
. sub(/\A\d{#{3-mod}},?/, '')
end
end
1234.delimited(8) #=> "0,001,234"
Updated by znz (Kazuhiro NISHIYAMA) over 5 years ago
Some printf
can use %'d
.
$ /usr/bin/printf "%'d\n" 1234
1,234
Updated by shyouhei (Shyouhei Urabe) over 5 years ago
znz (Kazuhiro NISHIYAMA) wrote:
Some
printf
can use%'d
.
Yes but that's not what the OP wants.
% printf "%'07d\\n" 1234
001,234
The output is different.
Updated by shevegen (Robert A. Heiler) over 5 years ago
The python example seems quite concise to me:
format(1234, '08,') # => '0,001,234'
format(1234, '8,') # => ' 1,234'
I can not say how useful this may be though.
The method-names seem a bit strange to me - format() seems very generic
and delimited() is .... hmmm. I am not sure with what this is "de-limited".
Updated by shan (Shannon Skipper) over 5 years ago
class Integer
def delimited(by: ',', digits: 0, padding: '0', every: 3)
extra_padding_size = digits.to_int - Math.log10(self).floor.succ
extra_padding = if extra_padding_size.positive?
Array.new(extra_padding_size, padding.to_str.chr)
end
(self.digits + extra_padding.to_a).each_slice(every).map do |triplet|
triplet.reverse.join
end.reverse.join(by.to_str)
end
end
N = 4_200_000
N.delimited
#=> "4,200,000"
N.delimited(by: '_')
#=> "4_200_000"
N.delimited(every: 2, by: '_')
#=> "4_20_00_00"
N.delimited(digits: 12)
#=> "000,004,200,000"
N.delimited(digits: 12, padding: 'X')
#=> "XXX,XX4,200,000"
Updated by Hanmac (Hans Mackowiak) over 5 years ago
because it is locale-dependent as duerst said, i think it should only be part of an intl gem where you can control the locale
Updated by ko1 (Koichi Sasada) over 5 years ago
- Status changed from Open to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
Updated by matz (Yukihiro Matsumoto) over 5 years ago
- Status changed from Assigned to Rejected
I agree with @duerst (Martin Dürst) and @Hanmac (Hans Mackowiak)
It's handy but it cannot be in the standard library.
Matz.
Updated by mame (Yusuke Endoh) about 3 years ago
- Related to Feature #18410: Proposal to make inspect include underscores on numerics added