我正在编写一个通用调用,用于通过JSON存储和检索数据.因此,当从JSON加载数据时,我可以验证它是TJSONNumber,但缺乏正确的方法来确定它是integer还是double.目前我是这样做的,但我想还有更好的方法吗?

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;

推荐答案

不幸的是,TJSONNumber不能告诉你实际的类型,所以你必须自己解析原始文本来弄清楚.

例如,使用TryStrToInt64()(而不是try..except),例如:

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

或者,您可以扫描JSON字符串中的'.''E'个字符(除了'+''-'之外,JSON数字中唯一允许的非数字字符),例如:

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

请注意,TJSONNumber也可以转换为UIntUInt64,因此您可能也要考虑处理这些类型.

Json相关问答推荐

SWIFT中的网络经理

使用自定义类型在Golang中解析JSON数组

在Snowflake中查询JSON时,属性名称是否支持绑定参数?

匹配来自不同数组的值

jq :遍历 json 并在键存在时检索集合

如何 Select 一个值,这是可选的 - 使用 jq

嵌套存储在字符串变量中的 JSON 对象

如何迭代、动态加载我的表单输入元素,然后在 React 中的表单提交上检索输入值?

如何在linux中用jq过滤json数组?

字典和对象的模型创建问题

序列化为json时如何忽略空列表?

Google GCM 服务器返回未经授权的错误 401

如何在golang中获取 struct 的json字段名称?

谷歌浏览器不允许我放置断点

使用 ajax 将 JSON 发送到 PHP

区分字符串和列表的 Pythonic 方式是什么?

JSON日期到Java日期?

在 Java 中比较两个 JSON 文件的最佳方法

无法将空值放入 JSON 对象

YAML 将 5e-6 加载为字符串而不是数字