how to reduce numbers' significance in JSON's stringify

我怕爱的太早我们不能终老 提交于 2019-12-02 20:30:41

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]"

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; 
}

The first way that comes to mind is to pre-process the array to round all the numbers to four 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 the unary plus operator to convert that back to a number.

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

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

A bit of overkill, but this should work 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

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

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!