Forum: Ruby on Rails formatting numbers with commas

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
4ba4bb954bcfec077d9708b540558926?d=identicon&s=25 Guido Sohne (Guest)
on 2006-01-24 18:26
(Received via mailing list)
I needed to format numbers with commas to make it more human
readable. Here's how I did it.

def commify(number)
     c = { :value => "", :length => 0 }
     r = number.to_s.reverse.split("").inject(c) do |t, e|
       iv, il = t[:value], t[:length]
       iv += ',' if il % 3 == 0 && il != 0
       { :value => iv + e, :length => il + 1 }
     end
     r[:value].reverse!
end

Am interested in how many better ways there are to do it. Maybe even
a one liner ...

-- G.
C8a634a01a2c4508360874bff7fb1a7f?d=identicon&s=25 Kevin Olbrich (olbrich)
on 2006-01-24 19:10
Guido Sohne wrote:
> I needed to format numbers with commas to make it more human
> readable. Here's how I did it.
>
> def commify(number)
>      c = { :value => "", :length => 0 }
>      r = number.to_s.reverse.split("").inject(c) do |t, e|
>        iv, il = t[:value], t[:length]
>        iv += ',' if il % 3 == 0 && il != 0
>        { :value => iv + e, :length => il + 1 }
>      end
>      r[:value].reverse!
> end
>
> Am interested in how many better ways there are to do it. Maybe even
> a one liner ...
>
> -- G.

Here's how I did it recently

num_with_commas =
number.to_s.reverse.gsub(/(\d{3})/,"\\1,").chomp(",").reverse

Note that this will run into trouble if you have decimal points in it.
If you do, just cut off that part of the string and paste it back on
after you add the commas.

_Kevin
Bd6167863690cb320d65bb9204619817?d=identicon&s=25 David Clements (Guest)
on 2006-01-24 19:12
(Received via mailing list)
On 1/24/06, Guido Sohne <guido.sohne@gmail.com> wrote:
>     end
>     r[:value].reverse!
> end
>
> Am interested in how many better ways there are to do it. Maybe even a one
> liner ...
>
> -- G.
>


Check out NumberHelper in the API, it is a one liner:

*number_with_delimiter*(number, delimiter=",")

Formats a number with a delimiter. Example:

   number_with_delimiter(12345678) => 12,345,678

 [ hide source <javascript:toggleSource('M000363_source')> ]

    # File
vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb,
line 75
75:       def number_with_delimiter(number, delimiter=",")
76:         number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/,
"\\1#{delimiter}")
77:       end
4ba4bb954bcfec077d9708b540558926?d=identicon&s=25 Guido Sohne (Guest)
on 2006-01-24 19:36
(Received via mailing list)
The gsub approach is much nicer. Exactly what I was looking for. Thanks!

-- G.
Ad7805c9fcc1f13efc6ed11251a6c4d2?d=identicon&s=25 Alex Young (Guest)
on 2006-01-24 19:39
(Received via mailing list)
Guido Sohne wrote:
>     r[:value].reverse!
> end
>
> Am interested in how many better ways there are to do it. Maybe even a
> one liner ...
Depends what you count as one line :-)

def commify(v)
  (s=v.to_s;x=s.length;s).rjust(x+(3-(x%3))).scan(/.{3}/).join(',').strip
end

Doesn't work for negative numbers, though, but it's quite fun...  This
works, but is boring:

v.to_s.reverse.gsub(/(\d{3})(?=\d)/x,'\1,').reverse
4ba4bb954bcfec077d9708b540558926?d=identicon&s=25 Guido Sohne (Guest)
on 2006-01-24 20:10
(Received via mailing list)
On Jan 24, 2006, at 6:38 PM, Alex Young wrote:

> def commify(v)
>  (s=v.to_s;x=s.length;s).rjust(x+(3-(x%3))).scan(/.{3}/).join
> (',').strip
> end

I tried to mess with the regex, /.{3}/ to get it to ignore '.'s and
stuff following it, but that breaks the neat slicing in three's ...
unless x=s.length - s.scan(/\..*/) ...

So far, only the gsub approach works for floating point numbers ...
but only if they have two or fewer digits past the '.' ...

irb(main):024:0> v = 1000000.0101
=> 1000000.0101
irb(main):025:0> v.to_s.reverse.gsub(/(\d{3})(?=\d)/x,'\1,').reverse
=> "1,000,000.0,101"
irb(main):026:0>

So which is gonna win when doing the floats? gsub or rjust+scan ? :-)

I like both approaches ...

-- G.
205bc8d44e9bc5c68d77dd412abcb3ce?d=identicon&s=25 Dan Shafer (Guest)
on 2006-01-24 23:42
(Received via mailing list)
After a good bit of hassle, I finally got Locomotive working on my OS
X box. Because it seems more comfortable with SQLite than with MySQL,
I'm using the former for the moment in preparation for the Rails
Studio in Pasadena this week.

I ran into a tiny issue which I'd like to understand better.

I created a SQLite table in the usual way:

sqlite3 depot_developer

Then I created a text table-creating file called create_products.sql
and stuck in the db folder of the Rails app's directory.

Then I switched to the db directory, launched sqlite3 and instructed
it to .read the newly created SQL file. It appeared to work
flawlessly. Indeed, when I ask SQLite3 for the .tables, I see the
products table there. Cool.

Then I tried to create the scaffold for the project and I got an error:

       create    test/fixtures/products.yml
        error  Before updating scaffolding from new DB schema, try
creating a table for your model (Product)

I tried again with the same result.

So I deleted the depot_development database and then looked at the
Locomotive video where I saw that it created a new database with an
initial table by:

sqlite3 depot_development < create_products.sql

This seemed kind of strange to me but I tried it and then ran the
scaffolding generation and it worked fine (or at least reported no
error).

Can anyone tell me why this happened? My big concern at the moment is
that the next time I need to add a table to this depot_development
database I don't want to lose my existing table by using the "<"
syntax rather than reading the table-creation SQL inside SQLite.

Thanks.
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
Dan Shafer
Technology Visionary - Technology Assessment - Documentation
"Looking at technology from every angle"
http://www.eclecticity.com
205bc8d44e9bc5c68d77dd412abcb3ce?d=identicon&s=25 Dan Shafer (Guest)
on 2006-01-25 01:09
(Received via mailing list)
You can ignore this question for my purposes, though it might be of
general interest. I decided after seeing how SQLite datatype support
worked that I would see if I could get MySQL working anyway. To my
amazement, it came right up and did what I expected. So I'm back
using MySQL and thus able to follow the Agile book much more easily.

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
Dan Shafer
Technology Visionary - Technology Assessment - Documentation
"Looking at technology from every angle"
http://www.eclecticity.com
This topic is locked and can not be replied to.