[ACCEPTED]-how to reduce numbers' significance in JSON's stringify-number-formatting

Accepted answer
Score: 48

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

a = [0.123456789123456789]
JSON.stringify(a, function(key, val) {
    return val.toFixed ? Number(val.toFixed(3)) : val;
})

>> "[0.123]"
Score: 9

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

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

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

Here's 4 the obligatory MDN link.


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

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

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

function precisify(n, places) { 
    var scale = Math.pow(10, places); 
    return Math.round(n * scale) / scale; 
}
Score: 3

The first way that comes to mind is to pre-process 6 the array to round all the numbers to four 5 digits:

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

​for (​var i=0; i<array.length; i++){
    array[i].x = +array[i].x.toFixed(4);
    array[i].y = +array[i].y.toFixed(4);
}

var json = JSON.stringify(array);

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

The .toFixed() function returns a string, so I've used 4 the unary plus operator to convert that 3 back to a number.

The second way that comes 2 to mind is to process the string output 1 by JSON.stringify():

json = json.replace(/(\.\d{4})(\d+)/g,"$1");
Score: 1

A bit of overkill, but this should work 1 in all situations.

function prepareArrayForJSON(array) {
    var i = 0;
    while (i < array.length) {
        if (typeof array[i] === 'number') {
            array[i] = array[i].toPrecision(4);
        } else if(typeof array[i] === 'object') {
            if (array instanceof Object) {
                prepareObjectForJSON(array[i]);
            } else if (array instanceof Array) {
                prepareArrayForJSON(array[i]);
            }
        }
    }
}

function prepareObjectForJSON(obj) {
    var i;
    for (i in obj) {
        if (obj.hasOwnProperty(i)) {
            if (typeof obj[i] === 'number') {
                obj[i] = obj[i].toPrecision(4);
            } else if(typeof obj[i] === 'object') {
                if (obj instanceof Object) {
                    prepareObjectForJSON(array[i]);
                } else if (obj instanceof Array) {
                    prepareArrayForJSON(obj[i]);
                }
            }
        }
    }
}

Enjoy yourself

Score: 0

Run over your array and apply the following 4 to all values.

 value = Math.round( value * 10000 ) / 10000;

Another possibility is to 3 store your coordinates internally as int 2 values (multiples of 10^-4) and just convert 1 them for output.

More Related questions