39

How would it be a nice way of handling this?

I already thought on removing the comma and then parsing to float.

Do you know a better/cleaner way?

Thanks

DanC
  • 8,595
  • 9
  • 42
  • 64

7 Answers7

83
parseFloat( theString.replace(/,/g,'') );
James
  • 109,676
  • 31
  • 162
  • 175
  • 19
    Please don't use regex. `.replace(',', '')` – Dogbert Jul 08 '10 at 16:19
  • He also specifically said he considered removing the comma, but is interested in other ways – Michael Mrozek Jul 08 '10 at 16:20
  • 30
    @Adam, let's say the number is 1 million, `"1,000,000"`, if you don't use a regex with the global flag, only the first comma will be replaced -> `"1000,000"`. – Christian C. Salvadó Jul 08 '10 at 16:21
  • 2
    @Adam - J-P's solution is more dynamic in that it covers multiple commas. – user113716 Jul 08 '10 at 16:22
  • @Michael - Depends on what the OP meant by 'removing the comma'. If OP meant that he would remove the comma from the markup completely, then it is a good alternative to keep the comma and have javascript remove it only when necessary. – user113716 Jul 08 '10 at 16:24
  • 6
    Yes, it's annoying that you have to resort to regexp to do a simple string replace when there may be more than one occurrence of the needle, but that's wacky JavaScript for you. An alternative idiom for when the needle might contain regex-special characters and you don't want to have to worry about escaping is `s.split(needle).join(replacement)`. – bobince Jul 08 '10 at 16:32
  • 8
    @Adam There is no reason *not* to use RegEx here – Josh Stodola Jul 08 '10 at 18:42
  • 1
    Ah. Sorry, had no idea that .replace replaces only once. – Dogbert Jul 08 '10 at 19:20
  • Why do people get so uptight about using regex? Most of the time when you do something like this it's to parse a handful of controls and the performance impact comes down to a few milliseconds. – David Sherret Nov 04 '13 at 17:42
18

I don't know why no one has suggested this expression-

parseFloat( theString.replace(/[^\d\.]/g,'') );

Removes any non-numeric characters except for periods. You don't need custom functions/loops for this either, that's just overkill.

micah
  • 7,596
  • 10
  • 49
  • 90
13

Nope. Remove the comma.

Matchu
  • 83,922
  • 18
  • 153
  • 160
  • 10
    This is not much of an answer see 999's answer below which actually does help. http://stackoverflow.com/a/3205751/111757 – Vicer Jan 18 '13 at 00:18
  • 2
    @Vicer: Strictly speaking, *999's* answer isn't much of an answer to *this* particular question: OP already knows how to remove commas from strings, and was asking if another technique exists. And the answer was "no". For future folks who come along who *don't* know how to remove commas, though, 999's answer is definitely more helpful, even if it doesn't actually answer the original question. But, hey. Since the only people who will visit this page anymore are Googling how to deal with numbers with commas, his is definitely the better answer for all future viewers. – Matchu Jan 19 '13 at 05:38
  • 2
    @Matchu Not necessarily, I came along looking for a very concise answer (I guess, technically, I had the same question as the OP). In my case your answer was an exercise of both accuracy and brevity (the OP would seem to agree). Anyway, just saying for some of us "future viewers", this answer is still better than 999's (hence my upvote). I would expect that if someone didn't know how to replace commas, they would Google that and never see this page in all likelihood. In my case, though I Googled and found this page's title matched, pretty closely, my search text. Thnx! – VoidKing Mar 21 '13 at 20:49
  • 1
    How would you go about handling this in de-DE locale? 12,500.50 in en-US is, well, 12,500.50 but in de-DE it is 12.500,50 leaving us with 12.50075. Anyone happen to have a library which handles this 'magic'? – Forty3 Nov 15 '17 at 18:16
6

You can use the string replace method, but not in a one liner as a regexp allows.

while(str.indexOf(',')!=-1)str= str.replace(',','');
parseFloat(str);

Or to make a single expression without a regexp=

return parseFloat(str.split(',').join(''));

I'd use the regexp.

kennebec
  • 102,654
  • 32
  • 106
  • 127
4

I don't have enough reputation to add a comment, but for anyone wondering on the performance for regex vs split/join, here's a quick fiddle: https://jsfiddle.net/uh3mmgru/

var test = "1,123,214.19";

var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
    var a = parseFloat(test.replace(/,/g,''));
}
var t1 = performance.now();
document.write('Regex took: ' + (t1 - t0) + ' ms');
document.write('<br>')

var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
    var b = parseFloat(test.split(',').join(''));
}
var t1 = performance.now();
document.write('Split/join took: ' + (t1 - t0) + ' ms');

The results I get are (for 1 million loops each):

Regex: 263.335 ms
Split/join: 1035.875 ms

So I think its safe to say that regex is the way to go in this scenario

Mogzol
  • 1,405
  • 1
  • 12
  • 18
0

What about a simple function to solve most of the common problems?

function getValue(obj) {
  Value = parseFloat( $(obj).val().replace(/,/g,'') ).toFixed(2);
  return +Value;
}

The above function gets values from fields (using jQuery) assuming the entered values are numeric (I rather validate fields while user is entering data, so I know for sure field content is numeric).

In case of floating point values, if well formatted in the field, the function will return a float point value correctly.

This function is far from complete, but it quickly fix the "," (comma) issue for values entered as 1,234.56 or 1,234,567. It will return valid number as far the content is numeric.

The + (plus) sign in front of the variable Value in the return command is a "dirty trick" used in JavaScript to assure the variable content returned will be numeric.

it is easy to modify the function to other purposes, such as (for instance), convert strings to numeric values taking care of the "," (comma) issue:

function parseValue(str) {
  Value = parseFloat( str.replace(/,/g,'') ).toFixed(2);
  return +Value;
}

Both operations can even be combined in one function. I.e.:

function parseNumber(item,isField=false) {
  Value = (isField) ? parseFloat( $(item).val().replace(/,/g,'') ).toFixed(2) : parseFloat( item.replace(/,/g,'') ).toFixed(2)
  return +Value;
}

In such case, if function is called result = parseNumber('12,092.98'); it will parse the value as it is a String. But if called as result = parseNumber('#MyField', true); it will try to obtain the value from '#MyField'.

As I said before, such functions are far from complete, and can be expanded in many ways. One idea is to check the first character of the given parameter (string) and decide based on the string format where to obtain the value to be parsed (if 1st character is = '#' then it is an ID from a DOM object, otherwise, if it begins with a number, it must be a string to be parsed).

Try it... Happy coding.

Julio Marchi
  • 730
  • 6
  • 15
0

Building on the idea from @kennebec, if you want to make sure that the commas are correct, and you don't want to replace commas, you could try something like this:

function myParse(num) {
  var n2 = num.split(",")
  out = 0
  for(var i = 0; i < n2.length; i++) {
    out *= 1000;
    out += parseFloat(n2[i])
  }
  return out
}
alert(myParse("1,432,85"));
// Returns 1432085, as the comma is misplaced.

It may not be as fast, but you wanted alternatives :)

bradlis7
  • 3,375
  • 3
  • 26
  • 34