как уменьшить значение чисел в stringify JSON - PullRequest
20 голосов
/ 18 февраля 2012

У меня есть массив с числами (координатами), и я хочу отобразить те, которые используют JSON, вот так:

 JSON.stringify(array);

Мой массив выглядит так:

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

Но я толькоинтересуют первые (скажем, 4) значащие цифры, то есть

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

Есть ли способ легко отбросить оставшиеся незначительные числа?

Ответы [ 5 ]

35 голосов
/ 18 февраля 2012

Native JSON.stringify принимает параметр replacer, который может быть функцией, преобразующей значения в любое необходимое:

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

>> "[0.123]"
8 голосов
/ 18 февраля 2012

Используйте Number#toPrecision или Number#toFixed, в зависимости от того, что больше соответствует вашим потребностям.Разница в том, что toFixed устанавливает количество цифр после десятичной точки, а toPrecision устанавливает все количество цифр.

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

Обратите внимание, что toFixed и toPrecision возвращают строки, поэтомувы, вероятно, захотите преобразовать их обратно в числа, прежде чем JSONiii их.

Вот обязательная ссылка MDN .


Вы также можете сделать что-то подобное,если вы хотите свернуть свой собственный.

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

Инкапсулированный в функцию, он может выглядеть примерно так:

function precisify(n, places) { 
    var scale = Math.pow(10, places); 
    return Math.round(n * scale) / scale; 
}
3 голосов
/ 18 февраля 2012

Первый способ, который приходит на ум, - это предварительно обработать массив, чтобы округлить все числа до четырех цифр:

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}]'

Функция .toFixed() возвращает строку,поэтому я использовал унарный оператор плюс, чтобы преобразовать его обратно в число.

Второй способ, который приходит на ум, - обработать вывод строки как JSON.stringify():

json = json.replace(/(\.\d{4})(\d+)/g,"$1");
1 голос
/ 18 февраля 2012

Немного излишества, но это должно работать во всех ситуациях.

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

Наслаждайся собой

0 голосов
/ 18 февраля 2012

Запустите ваш массив и примените следующее ко всем значениям.

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

Другая возможность - хранить ваши координаты внутри как значения int (кратные 10 ^ -4) и просто конвертировать их для вывода.

...