Can JSON values be numbers? - javascript

Can JSON values (not keys) be numbers, or do they HAVE to be strings only? So the following is valid.
{"number":"6"}
But is the following also valid?
{"number":6}

In JSON, 6 is the number six. "6" is a string containing the digit 6. So the answer to the question "Can json numbers be quoted?" is basically "no," because if you put them in quotes, they're not numbers anymore.
The only thing that needs to be between quotes is the property name (number).

It is valid JSON syntax. But beware that different programming languages will parse JSON differently..
https://www.freeformatter.com/json-validator.html

Json values can be
a string
a number
an object (JSON object)
an array
a boolean
null
See - https://www.w3schools.com/js/js_json_datatypes.asp

Related

JavaScript code to evaluate string arithmetic expression containing multiple arrays

I want to pass an arithmetic expression as a string to Javascript and this string can contain any number of numerical arrays which will be dynamically populated.
For Eg: I need to evaluate the below expression
(pmPdcpVolDlDrb+pmPdcpVolDlSrb)/8/1024 , Where both pmPdcpVolDlDrb and pmPdcpVolDlSrb are numeric arrays
pmPdcpVolDlDrb =[ Array containing values for sensor pmPdcpVolDlDrb read from storage]
pmPdcpVolDlDrb =[ Array containing values for sensor pmPdcpVolDlDrb read from storage]
This expression can change and the number of variables involved can also change. I need a generalized way of handling it. I wrote the below code and it serves my purpose. I need to know if there is a better and standard way for the same.
// Expression for evaluation where pmPdcpVolDlDrb and pmPdcpVolDlSrb are arrays
expression="(pmPdcpVolDlDrb+pmPdcpVolDlSrb)/8/1024"
// Seperating out the variables from the expression. In my case variable names always start with pm
variables=expression.split(/\W+/).filter(word => word.includes("pm"));
array=[]
for(i=0;i<variables.length;i++){
array[i]= [1,2,3,4]// Replace with actual code to get the values of arrays to be computed
if (i===0)
expression=expression.replace(variables[i],"a")
else
expression=expression.replace(variables[i],"array["+i+"][i]")
}
resultantArray=array[0].map((a, i) => eval(expression))

alternative to JSON.parse() for maintaining decimal precision?

I'm calling JSON.parse() to parse a JSON string which has small decimals.
The precision of the decimals is not being maintained after parsing. For example, a value like 3.1e-7 is being returned instead of the actual decimal.
How can I deserialize a JSON string in ng2+ while maintaining decimal precision?
UPDATE
I was thinking about mapping out the values from the string and then setting the values manually to the object after JSON.parse() but when I set a different small decimal number as a property value, the same number formatting occurs. So is this problem not necessarily unique to JSON.parse() but to Javascript in general? Or does JSON.parse() somehow configure property types in a fixed way?
As soon as you pass your JSON string through JSON.parse, you'll lose precision because of the way floating point math works. You'll need to store the number as an object designed for storing arbitrary-precision numbers, and you'll need to fiddle with the string itself before parsing it. The simplest way is with regexes. JSON is a context free grammar, and regexes work on regular grammars, so the warning applies:
WARNING: PARSING CFG WITH REGEX MAY SUMMON ZALGO
This regex should turn the numbers in your JSON into strings:
let stringedJSON = origJSON.replace(/:\s*([-+Ee0-9.]+)/g, ': "uniqueprefix$1"');
But I haven't tested it extensively and it definitely will screw things up if you have keys that are something like data:42.
Assuming it worked correctly, stringedJSON should now be something like {"foo": "uniqueprefix0.00000017", "bar": "an actual string"}. You can parse this with JSON.parse without losing precision, but uniqueprefix0.00000017 isn't what you want. JSON.parse can be called with an extra reviver argument, which transforms values passed to it before returning them. You can use this to convert your data back into a useful form:
let o = JSON.parse(stringedJSON, (key, value) => {
// only changing strings
if (typeof value !== 'string') return value;
// only changing number strings
if (!value.startsWith('uniqueprefix')) return value;
// chop off the prefix
value = value.slice('uniqueprefix'.length);
// pick your favorite arbitrary-precision library
return new Big(value);
});

Hash code which contains more than 16 characters?

I would like to apply a hash code solution on my webpage which is more compact than MD5 and SHA-1, because I want to use them as keys in a JSON hash table.
Or equivalently: how can I convert a hexadecimal MD5 hash to a higher base number system? The higher the better, till the words can be used as keys in a JSON hash. For example instead of:
"684591beaa2c8e2438be48524f555141" hexadecimal MD5 hash I would prefer "668e15r60463kya64xq7umloh" which is a base 36 number and the values are equal.
I made the calculation in Ruby:
"684591beaa2c8e2438be48524f555141".to_i(16).to_s(36)
=> 668e15r60463kya64xq7umloh
Because it handles the big decimal value of the hexadecimal MD5 hash (138600936100279876740703998180777611585)
Unlike JavaScript, in JavaScript I get a float value, which is rounded. So I get the same 36-base value for different MD5 hashes.
Ruby
You could return base64digest directly :
require 'digest'
Digest::MD5.hexdigest 'your_page'
#=> "a6b580481008e60df9350de170b7e728"
p Digest::MD5.base64digest 'your_page'
#=> "prWASBAI5g35NQ3hcLfnKA=="
Javascript
If you already have a hex string, a comment from this previous answer seems to work fine :
btoa("a6b580481008e60df9350de170b7e728".match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a, 16));} ).join(""))
#=> "prWASBAI5g35NQ3hcLfnKA=="

Why does jquery remove brackets from data html5 attribute?

I am trying to get the content of a data attribute with jquery but returned data is not what I had set.
With this simple example:
<div id="test" data-test="[1]"></div>
But $('#test').data('test') returns 1 instead of [1]
No problem using pure javascript.
View it online: https://jsfiddle.net/jojhm2nd/
jQuery's data is not an attribute accessor function. (This is a common mistake, easily made.) To just access the attribute, use attr.
$("#test").attr("data-test");
data does read data-* attributes, but only to initialize jQuery's data cache for that element. (And it never writes attributes.) It does a whole series of things including changing names (data-testing-one-two-three becomes testingOneTwoThree, for instance) and interpreting the values. In this case, it interprets the value as an array because it starts with [. When you show that array with alert, it's coerced to a string, and when you coerce an array to a string, that does an Array#join. If your attribute had been [1, 2], for instance, you'd've seen 1,2 as the result.
From the docs linked above:
Every attempt is made to convert the string to a JavaScript value (this includes booleans, numbers, objects, arrays, and null). A value is only converted to a number if doing so doesn't change the value's representation. For example, "1E02" and "100.000" are equivalent as numbers (numeric value 100) but converting them would alter their representation so they are left as strings. The string value "100" is converted to the number 100.
When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string.
jQuery does magic when you use the .data method.
From the jQuery website:
Every attempt is made to convert the string to a JavaScript value
(this includes booleans, numbers, objects, arrays, and null).
You can use the .attr method and do:
$('#test').attr('data-test');

Converting a long number string into an array

So, let's say I have a string composed a very large number, say "123456789101112131415" for example. How do I convert that string into an array with those values in it?
Quite Easily Done:
"123456789101112131415".split("")

Categories

Resources