-3

I am trying to convert quoted numbers (string) to automatic type by removing quotes from them via regex. Like from "123" to 123.

I am using JSON.parse reviver function but cant seem to replace it.

What I need:

  1. replace in reviver should work. See code below
  2. Generic correct regex which can handle all kind of numbers. I am not sure if i am using right regex.
  3. Is there any library already doing stuff like this ? Please mention

JSFIDDLE: https://jsfiddle.net/bababalcksheep/j1drseny/

CODE:

var test = {
   "int": 123,
   "intString": "123",
   "Scientific_1_String": "5.56789e+0",
   "Scientific_1": 5.56789e+0,
   "Scientific_2_String": "5.56789e-0",
   "Scientific_2": 5.56789e-0,
   "Scientific_3_String": "3.125e7",
   "Scientific_3": 3.125e7,
   "notNumber": "675.805.714",
   "dg": "675-805-714",
   "hex": "675.805.714",
   "trueString": "true",
   "trueBool": true,
   "falseString": "false",
   "falseBool": false,

 };
 test = JSON.stringify(test);
 var parsedJson = JSON.parse(test, function(key, value) {
   if (typeof value === 'string') {
     if (value === 'false') {
       return false;
     } else if (value === 'true') {
       return true;
     } else {
       // try to remove quotes from number types
       value = value.replace(/"(-?[\d]+\.?[\d]+)"/g, "$1");
       return value;
     }
   } else {
     return value;
   }
 });
 console.log(parsedJson);
django
  • 2,809
  • 5
  • 47
  • 80

2 Answers2

4

You can use the Number() function to convert a string to a number. If the string is not a number, this function will return NaN.

This code should work:

const test = JSON.stringify({
  "int": 123,
  "intString": "123",
  "Scientific_1_String": "5.56789e+0",
  "Scientific_1": 5.56789e+0,
  "Scientific_2_String": "5.56789e-0",
  "Scientific_2": 5.56789e-0,
  "Scientific_3_String": "3.125e7",
  "Scientific_3": 3.125e7,
  "notNumber": "675.805.714",
  "dg": "675-805-714",
  "hex": "675.805.714",
  "trueString": "true",
  "trueBool": true,
  "falseString": "false",
  "falseBool": false,
});

const parsed = JSON.parse(test, (key, value) => {
  if (typeof value === 'string') {
    const valueNumber = Number(value);
    if (!Number.isNaN(valueNumber)) {
      return valueNumber;
    }
  }
  return value;
});

console.log(parsed);
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
  • does Number() handle all types of numbers ? This is good option but i would prefer not to change decimals or convert exponentiation that's why i am replacing quote marks. Can you explain why repalce is not working. – django Dec 07 '16 at 15:48
  • 1
    @django What do you mean by "all types of numbers"? I think you should add sample input and desired output to your question. And replacing quote marks is not working because the string doesn't actually contain the quote marks. The quote marks only inform the interpreter where does the string begin and where does it end. The actual content of the string is what's *between* the quote marks. – Michał Perłakowski Dec 07 '16 at 15:55
0

Why stringify it then process it, when it's much easier to do it on the JSON object, something like:

var fixedTest = Object.keys(test).reduce((fixedObj, field) => {
  fixedObj[field] = isNaN(test[field]) ? test[field] : +test[field];
  return fixedObj;
}, {});
Ovidiu Dolha
  • 5,335
  • 1
  • 21
  • 30
  • 1
    Probably because the actual input is a JSON string. Also, there's no such thing as "JSON object". See [What is the difference between JSON and Object Literal Notation?](http://stackoverflow.com/q/2904131/3853934) – Michał Perłakowski Dec 07 '16 at 14:41
  • And it's better to use the `Number()` function instead of the unary `+`. Explicit is better than implicit. – Michał Perłakowski Dec 07 '16 at 14:48
  • 1. you know what i meant; 2. still a valid solution, no reason to downvote it 3. nowhere is mentioned that input is a string – Ovidiu Dolha Dec 07 '16 at 14:50
  • originally i have stringyfied data so i am trying to emulate that. and I am useing parseJson because it could be nested to any level – django Dec 07 '16 at 15:45