Commas in Numbers
From Erlang Community
| Revision as of 01:32, 26 August 2006 (edit) Cyberlync (Talk | contribs) ← Previous diff |
Revision as of 23:15, 3 September 2006 (edit) (undo) Bfulgham (Talk | contribs) Next diff → |
||
| Line 44: | Line 44: | ||
| In addition to Erlang's various other string-related ills (mainly poor memory and time performance), it has a very limited set of regular expressions. For example, our implementation of partition_number is over twice as long as the [[http://schemecookbook.org/view/Cookbook/NumberRecipeCommas][Scheme alternative] because it has no look-ahead (or negative look-ahead) searching functionality. | In addition to Erlang's various other string-related ills (mainly poor memory and time performance), it has a very limited set of regular expressions. For example, our implementation of partition_number is over twice as long as the [[http://schemecookbook.org/view/Cookbook/NumberRecipeCommas][Scheme alternative] because it has no look-ahead (or negative look-ahead) searching functionality. | ||
| - | [[Category:CookBook]] | + | [[Category:CookBook]][[Category:StringRecipes]][[Category:ListRecipes]][[Category:NumberRecipes]] |
Revision as of 23:15, 3 September 2006
Problem
You need to format a number for printing with commas (or other locale-dependant marks) in the appropriate places. This is important for creating human-legible print copies of reports.
Solution
Use the Perl-compatible regular expression engine to insert the commas where needed. It's simplest to reverse the string prior to the regexp-pass so that we can hop over any decimal portion. Then reverse the string back on return.
partition_number(Number, Separator) ->
SepChar = hd(Separator),
NumStr = if
is_integer(Number) -> hd(io_lib:format("~B", [Number]));
is_float(Number) -> hd(io_lib:format("~f", [Number]));
true -> Number
end,
% If there is a decimal point, use that as the starting point
{ChgStr, Remain} = case regexp:first_match(NumStr, "\\.") of
{match,Start,Length} ->
{string:substr(NumStr, 1, Start - 1),
string:substr(NumStr,Start,string:len(NumStr))};
nomatch -> {NumStr, ""}
end,
{ok, Subs, _} = regexp:gsub(lists:reverse(ChgStr),
"([0-9][0-9][0-9])", "&" ++ Separator),
Final = case lists:nth(string:len(Subs), Subs) of
SepChar -> string:substr(Subs, 1, string:len(Subs) - 1);
_ -> Subs
end,
lists:reverse(Final) ++ Remain.
|
While this function works, it would be better if it checked for someone passing the separator parameter as a character (rather than a string).
Here's an example of partition_number in action:
1> partition_number(1918928282, ","). "1,918,928,282" 2> partition_number(1982928828, "'"). "1'982'928'828" 3> partition_number(1982928828.12345, "'"). "1'982'928'828.123450" |
In addition to Erlang's various other string-related ills (mainly poor memory and time performance), it has a very limited set of regular expressions. For example, our implementation of partition_number is over twice as long as the [[1][Scheme alternative] because it has no look-ahead (or negative look-ahead) searching functionality.

Digg It
Del.icio.us
Reddit
Facebook
Stumble Upon
Technorati

