Reputation: 297
I have the following json object:
[{
"WEIGHTED_ARR_LAST_SLP": "0.03801186624130076",
"SLIPPAGE_INTERVAL_VWAP_BPS": "10.2711",
"ROOT_ORDER_ID": "735422197553491",
"ARRIVAL_MID_PX": "93.6100",
"WEIGHTED_ARR_SLP": "0.12323190317127024",
"AVG_PX": "93.6586",
"LEAVES_QTY": "0",
"WEIGHT": "0.02372627566400397",
"PARTICIPATION_RATE": "0E-12",
"LOCAL_REF_END_TIME": "2016-09-06 06:00:27.775",
"WEIGHTED_IVWAP_SLP": "0.2436949499725512",
"NOTIONAL_USD": "477940",
"LIQ_CONSUMPTION": "15.21",
"EXEC_QTY": "5103",
"CL_ORD_ID": "7245294057012908344",
"LOCAL_REF_START_TIME": "2016-09-06 05:59:57.844",
"SLIPPAGE_END_LAST_ARR_LAST_BPS": "1.6021",
"IVWAP_PX": "93.5625",
"LIMIT_PX": "93.6100",
"ORDER_ID": "735422197553491",
"SLIPPAGE_ARR_MID_BPS": "5.1939",
"ORDER_QTY": "5103",
"EXECUTION_STYLE": "2", {"ORDER_QTY": "5100", ..........}
}]
I want to coonvert only "Ord Qty", "Exec Qty", "AVG Px", "Notional", "Limit Px", "Arrival Px" "Arrival Px Slpg", "IVWAP Px Slpg", "LIQ Consumption"
to Number; and then display WEIGHTED_IVWAP_SLP
& WEIGHTED_ARR_SLP
with 4 decimal points, instead of so many. I'm trying to do it in the following way:
var jsondata = document.getElementById("jsonArray").value;
var jsondataObj = JSON.parse(jsondata);
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var parsedData = jsondataObj.map(function(obj) {
return Object.keys(obj).reduce(function(memo, key) {
var value = obj[key];
//console.log(value);
memo[key] = isNumeric(value) ? Number(value).toFixed(4) : value;
//localStorage.setItem("storeditem", value);
return memo;
}, {})
});
But this is converting all of fields of numbers with 4 decimal point. How to convert only specific fields?
Upvotes: 0
Views: 147
Reputation: 350167
You can modify your code slightly by adding a filter on the keys, before launching the reduce()
. Secondly, you could put an extra condition in your ternary operator, to deal with the two fields that should get 4 decimal digits:
var parsedData = jsondataObj.map(function(obj) {
return Object.keys(obj).filter (
key => ["ORDER_QTY", "EXEC_QTY", "AVG_PX", "NOTIONAL_USD", "LIMIT_PX",
"ARRIVAL_MID_PX", "WEIGHTED_ARR_SLP", "WEIGHTED_IVWAP_SLP",
"LIQ_CONSUMPTION"].includes(key)
).reduce(function(memo, key) {
var value = obj[key];
memo[key] = !isNumeric(value) ? value
: ["WEIGHTED_IVWAP_SLP", "WEIGHTED_ARR_SLP"].includes(key)
? Number(value).toFixed(4)
: Number(value);
return memo;
}, Object.assign({}, obj))
});
Note that you must then also pass a copy of the original object as initial value for reduce
. For this Object.assign
can be used.
Also, be aware that .toFixed
turns a number back to string type, as this is the only way to actually ensure you see 4 decimal digits. If you want to really have the number type, then apply Number()
to that result again:
Number(Number(value).toFixed(4))
Of course, trailing decimal zeroes will not display when you output such numbers without formatting.
var jsondata = `[{
"WEIGHTED_ARR_LAST_SLP": "0.03801186624130076",
"SLIPPAGE_INTERVAL_VWAP_BPS": "10.2711",
"ROOT_ORDER_ID": "735422197553491",
"ARRIVAL_MID_PX": "93.6100",
"WEIGHTED_ARR_SLP": "0.12323190317127024",
"AVG_PX": "93.6586",
"LEAVES_QTY": "0",
"WEIGHT": "0.02372627566400397",
"PARTICIPATION_RATE": "0E-12",
"LOCAL_REF_END_TIME": "2016-09-06 06:00:27.775",
"WEIGHTED_IVWAP_SLP": "0.2436949499725512",
"NOTIONAL_USD": "477940",
"LIQ_CONSUMPTION": "15.21",
"EXEC_QTY": "5103",
"CL_ORD_ID": "7245294057012908344",
"LOCAL_REF_START_TIME": "2016-09-06 05:59:57.844",
"SLIPPAGE_END_LAST_ARR_LAST_BPS": "1.6021",
"IVWAP_PX": "93.5625",
"LIMIT_PX": "93.6100",
"ORDER_ID": "735422197553491",
"SLIPPAGE_ARR_MID_BPS": "5.1939",
"ORDER_QTY": "5103",
"EXECUTION_STYLE": "2"
}]`;
var jsondataObj = JSON.parse(jsondata);
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var parsedData = jsondataObj.map(function(obj) {
return Object.keys(obj).filter (
key => ["ORDER_QTY", "EXEC_QTY", "AVG_PX", "NOTIONAL_USD", "LIMIT_PX",
"ARRIVAL_MID_PX", "WEIGHTED_ARR_SLP", "WEIGHTED_IVWAP_SLP",
"LIQ_CONSUMPTION"].includes(key)
).reduce(function(memo, key) {
var value = obj[key];
memo[key] = !isNumeric(value) ? value
: ["WEIGHTED_IVWAP_SLP", "WEIGHTED_ARR_SLP"].includes(key)
? Number(value).toFixed(4)
: Number(value);
return memo;
}, Object.assign({}, obj))
});
console.log(parsedData);
Upvotes: 1
Reputation: 3792
This is kind of doing your job for you right? Well, this answer doesn't use your code, but you should be able to apply it just the same. This uses language constructs such as if
, for
and for ... in
as opposed to methods of Array
like map
, reduce
, and filter
.
var a = [{
"WEIGHTED_ARR_LAST_SLP": "0.03801186624130076",
"SLIPPAGE_INTERVAL_VWAP_BPS": "10.2711",
"ROOT_ORDER_ID": "735422197553491",
"ARRIVAL_MID_PX": "93.6100",
"WEIGHTED_ARR_SLP": "0.12323190317127024",
"AVG_PX": "93.6586",
"LEAVES_QTY": "0",
"WEIGHT": "0.02372627566400397",
"PARTICIPATION_RATE": "0E-12",
"LOCAL_REF_END_TIME": "2016-09-06 06:00:27.775",
"WEIGHTED_IVWAP_SLP": "0.2436949499725512",
"NOTIONAL_USD": "477940",
"LIQ_CONSUMPTION": "15.21",
"EXEC_QTY": "5103",
"CL_ORD_ID": "7245294057012908344",
"LOCAL_REF_START_TIME": "2016-09-06 05:59:57.844",
"SLIPPAGE_END_LAST_ARR_LAST_BPS": "1.6021",
"IVWAP_PX": "93.5625",
"LIMIT_PX": "93.6100",
"ORDER_ID": "735422197553491",
"SLIPPAGE_ARR_MID_BPS": "5.1939",
"ORDER_QTY": "5103",
"EXECUTION_STYLE": "2"
}];
var fieldsToConvertToNumbers = [
"ORDER_QTY", "EXEC_QTY", "AVG_PX",
"NOTIONAL_USD", "LIMIT_PX", "ARRIVAL_MID_PX",
"WEIGHTED_IVWAP_SLP", "LIQ_CONSUMPTION"
];
for (var i = 0; i < a.length; ++i) {
var b = a[i];
for (var j = 0; j < fieldsToConvertToNumbers.length; ++j) {
var field = fieldsToConvertToNumbers[j];
if (field in b) {
var value = parseFloat(b[field]);
if (!isNaN(value))
b[field] = value;
}
}
}
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(JSON.stringify(a, null, ' ')));
document.body.appendChild(pre);
Use parseFloat
to convert the values to numbers, but be sure to check for NaN
results before deciding to update the value. Use IsNaN
for that. Don't think you really need to use !
IsFinite
, but knock yourself out.
So now you want to use toFixed
to fix your string display.
var text = (3.1415926535897932384626433832795028841971).toFixed(4);
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(text));
document.body.appendChild(pre);
So now you can use toFixed
to convert your numbers to strings that have only 4 decimal places of precision. However, they are strings instead of numbers. So you have to parse them back using parseFloat
.
var a = [{
"WEIGHTED_ARR_LAST_SLP": "0.03801186624130076",
"SLIPPAGE_INTERVAL_VWAP_BPS": "10.2711",
"ROOT_ORDER_ID": "735422197553491",
"ARRIVAL_MID_PX": "93.6100",
"WEIGHTED_ARR_SLP": "0.12323190317127024",
"AVG_PX": "93.6586",
"LEAVES_QTY": "0",
"WEIGHT": "0.02372627566400397",
"PARTICIPATION_RATE": "0E-12",
"LOCAL_REF_END_TIME": "2016-09-06 06:00:27.775",
"WEIGHTED_IVWAP_SLP": "0.2436949499725512",
"NOTIONAL_USD": "477940",
"LIQ_CONSUMPTION": "15.21",
"EXEC_QTY": "5103",
"CL_ORD_ID": "7245294057012908344",
"LOCAL_REF_START_TIME": "2016-09-06 05:59:57.844",
"SLIPPAGE_END_LAST_ARR_LAST_BPS": "1.6021",
"IVWAP_PX": "93.5625",
"LIMIT_PX": "93.6100",
"ORDER_ID": "735422197553491",
"SLIPPAGE_ARR_MID_BPS": "5.1939",
"ORDER_QTY": "5103",
"EXECUTION_STYLE": "2"
}];
var fieldsToConvertToNumbers = [
"ORDER_QTY", "EXEC_QTY", "AVG_PX",
"NOTIONAL_USD", "LIMIT_PX", "ARRIVAL_MID_PX",
"LIQ_CONSUMPTION"
];
var fieldsToConvertToFixedNumbers = [
"WEIGHTED_IVWAP_SLP", "WEIGHTED_ARR_SLP"
];
for (var i = 0; i < a.length; ++i) {
var b = a[i];
for (var j = 0; j < fieldsToConvertToNumbers.length; ++j) {
var field = fieldsToConvertToNumbers[j];
if (field in b) {
var value = parseFloat(b[field]);
if (!isNaN(value))
b[field] = value;
}
}
for (var j = 0; j < fieldsToConvertToFixedNumbers.length; ++j) {
var field = fieldsToConvertToFixedNumbers[j];
if (field in b) {
var value = parseFloat(b[field]);
if (!isNaN(value))
b[field] = parseFloat(value.toFixed(4));
}
}
}
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(JSON.stringify(a, null, ' ')));
document.body.appendChild(pre);
So now only the specific fields have 4 decimal places. And they're numbers, not strings.
Upvotes: 1
Reputation: 5041
Here you have a practical example:
var x = {
a: '1.11111',
b: '2.22222',
c: '3.33333',
d: '4.444444',
e: '5.55555'
}
var y = ['a', 'd'];
for(key in x) {
if(y.indexOf(key) != -1) {
x[key] = Number(x[key]).toFixed(2);
}
}
console.log(x);
X is your object and Y is an array containing the list of keys you want to convert to fixed, or whatever you want to do. When going through the keys, if the key is inside that array, you do your thing.
https://jsfiddle.net/dtuLxzy6/
Upvotes: 0