Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find out if a TJSONNumber is double or Integer?

I am writing a general calls to store and retrieve data via JSON. So when loading the data from JSON I can verify that it is a TJSONNumber but lack a proper way to find out if it is integer or double. Currently I do it this way, but I guess there are better ways?

FDataStore: TDictionary<string, Variant>;


for index := 0 to Value.Count - 1 do begin
   Pair := Value.Pairs[Index];
   if Pair.JsonValue is TJSONNumber then
        try
          FDataStore.AddOrSetValue(Pair.JsonString.Value, (Pair.JsonValue as TJSONNumber).AsInt);
        except
          FDataStore.AddOrSetValue(Pair.JsonString.Value, (Pair.JsonValue as TJSONNumber).AsDouble);
        end;
end;
like image 394
Wolfgang Bures Avatar asked Oct 15 '25 03:10

Wolfgang Bures


1 Answers

Unfortunately, TJSONNumber doesn't tell you the actual type, so you have to parse the original text to figure it out yourself.

For instance, by using TryStrToInt64() (rather than try..except), eg:

var
  IntValue: Int64;
  V: Variant;

if TryStrToInt64(TJSONNumber(Pair.JsonValue).Value, IntValue) then
begin
  if IntValue >= Min(Integer) and IntValue <= Max(Integer) then
    V := Integer(IntValue)
  else
    V := IntValue;
end else
  V := TJSONNumber(Pair.JsonValue).AsDouble);

FDataStore.AddOrSetValue(Pair.JsonString.Value, Value);

Alternatively, you could scan the JSON string for '.' and 'E' characters (the only non-digit characters allowed in a JSON number besides '+' and '-'), eg:

var
  V: Variant;

if LastDelimiter('.Ee', TJSONNumber(Pair.JsonValue).Value) = 0 then
begin
  var IntValue := TJSONNumber(Pair.JsonValue).AsInt64;
  if IntValue >= Min(Integer) and IntValue <= Max(Integer) then
    V := Integer(IntValue)
  else
    V := IntValue
end
else
  V := TJSONNumber(Pair.JsonValue).AsDouble;

FDataStore.AddOrSetValue(Pair.JsonString.Value, V);

Note that TJSONNumber is also convertible to UInt and UInt64, so you may want to consider handling those types, as well.

like image 61
Remy Lebeau Avatar answered Oct 17 '25 13:10

Remy Lebeau