Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to reduce numbers' significance in JSON's stringify

Tags:

I have an array with numbers (coordinates) and I want to display those using JSON like so

 JSON.stringify(array); 

My array looks like:

[{"x":-0.825,"y":0},  {"x":-1.5812500000000003,"y":-0.5625},  {"x":-2.2515625000000004,"y":-1.546875}] 

But I'm only interested in the first (lets say) 4 significant digits, i.e.

[{"x":-0.825,"y":0},  {"x":-1.5813,"y":-0.5625},  {"x":-2.2516,"y":-1.5469}] 

Is there a way to easily ditch the remaining insignificant numbers?

like image 411
dr jerry Avatar asked Feb 18 '12 08:02

dr jerry


People also ask

What is replacer in JSON Stringify?

let json = JSON.stringify(value [, replacer, space]) The value is the value to convert to a JSON string. The replacer is either a function that alters the behavior of the stringification process or an array which servers as a filter for the properties of the value object to be included in the JSON string.

Does JSON Stringify call toJSON?

JSON.stringify() calls toJSON with one parameter, the key , which has the same semantic as the key parameter of the replacer function: if this object is a property value, the property name. if it is in an array, the index in the array, as a string. if JSON.stringify() was directly called on this object, an empty string.

What is the time complexity of JSON Stringify?

It's considered O(n) as simple grammar doesn't require even lookaheads.

Does JSON Stringify have a limit?

So as it stands, a single node process can keep no more than 1.9 GB of JavaScript code, objects, strings, etc combined. That means the maximum length of a string is under 1.9 GB. You can get around this by using Buffer s, which store data outside of the V8 heap (but still in your process's heap).


2 Answers

Native JSON.stringify accepts the parameter replacer, which can be a function converting values to whatever is needed:

a = [0.123456789123456789] JSON.stringify(a, function(key, val) {     return val.toFixed ? Number(val.toFixed(3)) : val; })  >> "[0.123]" 
like image 107
georg Avatar answered Sep 27 '22 18:09

georg


Use Number#toPrecision or Number#toFixed, whichever suits your needs better. The difference is that toFixed sets the number of digits after the decimal point, and toPrecision sets the entire number of digits.

var foo = 1.98765432;  console.log(foo.toPrecision(5)); // 1.9877 

Note that toFixed and toPrecision return strings, so you'll probably want to convert them back to numbers before JSONifying them.

Here's the obligatory MDN link.


You can also do something like this, if you want to roll your own.

Math.round(1.98765432 * 10000) / 10000 // 1.9877 

Encapsulated in a function, it might look something like this:

function precisify(n, places) {      var scale = Math.pow(10, places);      return Math.round(n * scale) / scale;  } 
like image 23
Dagg Nabbit Avatar answered Sep 27 '22 18:09

Dagg Nabbit