5

I have a JSON file that contains numbers of type float. I would like to convert them to two decimal places before using the file in a react application. I understand that I need to use number.toFixed(2) to achieve that. How could I achieve that in the JSON file? A sample of the file:

[
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 3457.7132034355964,
    "value_avg_minus_stdv": 3415.2867965644036,
},
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 4457.7132034355964,
    "value_avg_minus_stdv": 3425.2867965644036,
}
]

The final result should be :

[
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 3457.71,
    "value_avg_minus_stdv": 3415.29,
},
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 4457.71,
    "value_avg_minus_stdv": 3425.29,
}
]

Thanks!

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
Derrick Omanwa
  • 457
  • 1
  • 5
  • 23
  • you would have to manually loop this array and apply toFixed on each property you desire to update – Sudhanshu Kumar Jun 19 '20 at 09:24
  • btw, you have no [JSON](https://json.org/), because JSON is a string. do you want to get a JSON or parse it? – Nina Scholz Jun 19 '20 at 09:27
  • `toFixed()` will produce a string, not a number as in your example. To round the numbers to two fraction digits, use [`Math.round()`](https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Math/round) with a factor like so: `x = Math.round(x * 100) / 100`. Note that the precision of floating point numbers may not exactly represent these numbers. – Lucero Jun 19 '20 at 09:30

5 Answers5

5

You could pass reviver function to the JSON.parse method to prescribes how the value originally produced by parsing is transformed, before being returned:

JSON.parse(jsonString, (key, value) =>
  typeof value === "number" ? Math.round(value * 100) / 100 : value
);

Replace Math.round(value * 100) / 100 with Math.round((value + Number.EPSILON) * 100) / 100 or +value.toFixed(2) or other methods as you wish.

More about JSON.parse

hangindev.com
  • 4,573
  • 12
  • 28
1

use toFixed

Like this

[
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 3457.7132034355964,
    "value_avg_minus_stdv": 3415.2867965644036,
},
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 4457.7132034355964,
    "value_avg_minus_stdv": 3425.2867965644036,
}
].map(x => ({
    ...x,
    value_avg_plus_stdv: +x.value_avg_plus_stdv.toFixed(2),
    value_avg_minus_stdv: +x.value_avg_minus_stdv.toFixed(2)
}))

Edit - toFixed will return a string, so add a + to convert it to number

gdh
  • 13,114
  • 2
  • 16
  • 28
0

You will need to loop the array of objects, and apply the function you mentioned on each number property.

First you will need to parse that JSON to get the JavaScript Object, and then apply something like this snippet:

const newArray = yourArray.map((obj) => ({
      ...obj,
      value_avg_plus_stdv: +obj.value_avg_plus_stdv.toFixed(2),
      value_avg_minus_stdv: +obj.value_avg_minus_stdv.toFixed(2),
    }));

The + on the toFixed() will convert the strings to numbers

mcarn
  • 76
  • 6
0

Let's go through your problem step-by-step

1) Get the file

In the further steps I will assume that you have already got the file and read its content into a String, I will call it rawInput from now on.

2) Convert your String into an object

var rawInput = `[
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 3457.7132034355964,
    "value_avg_minus_stdv": 3415.2867965644036
},
{
    "module": "prado2",
    "current_value": 3437.0,
    "value_avg": 3436.5,
    "value_avg_plus_stdv": 4457.7132034355964,
    "value_avg_minus_stdv": 3425.2867965644036
}
]`;
var input = JSON.parse(rawInput);

Now fix your object's items:

input

3) Make the conversion for numeric fields:

for (let item of input)
    for (let att in item)
        if (typeof item[att] === "number") item[att] = item[att].toFixed(2);

4) Convert it back to String:

var output = JSON.stringify(input)

5) Output

"[{\"module\":\"prado2\",\"current_value\":\"3437.00\",\"value_avg\":\"3436.50\",\"value_avg_plus_stdv\":\"3457.71\",\"value_avg_minus_stdv\":\"3415.29\"},{\"module\":\"prado2\",\"current_value\":\"3437.00\",\"value_avg\":\"3436.50\",\"value_avg_plus_stdv\":\"4457.71\",\"value_avg_minus_stdv\":\"3425.29\"}]"
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • The final result shown by the OP contains numbers, not strings... – Lucero Jun 19 '20 at 13:23
  • @Lucero it is shown similarly as the input, which was a file. And the op was telling us that he/she intends to change the content of that file before using it in React. Since the question indicated a file output, I have converted the result into a string. If an object is needed, then JSON.stringify becomes unnecessary. – Lajos Arpad Jun 19 '20 at 14:03
  • The output being a string was not what I meant; the *numbers* being strings is what I meant. – Lucero Jun 20 '20 at 14:49
  • @Lucero I see. They need to be strings, because otherwise you won't be able to enforce the format of two decimals. – Lajos Arpad Jun 20 '20 at 17:02
0

If you just need to truncate the numbers to a specified number of digits here is a command line tool that does that.

https://pypi.org/project/jsonvice/

Its written in python but has the logic in it. You can also choose whether to round, truncate or floor the numbers.

disclaimer I'm the author, but I ran in to this issue when compressing large machine learning models.

deftio
  • 51
  • 6