You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让JSON序列化工具处理嵌套对象并保留指定浮点数格式

解决JSON序列化时嵌套对象指定字段保留浮点数格式的问题

问题背景

后端返回的JSON包含形如10.0、20.0的浮点数,UI接收后这类值会被自动转为整数(10、20),但业务需要保留浮点数格式;而带小数部分的浮点数(如20.1)能正常保留格式。基于stringify-with-floats修改的代码仅支持顶层字段保留浮点数,嵌套对象的指定字段(如bar.baz)无法生效。

原代码问题分析

原代码的jsonReplacer函数仅通过当前层级的key匹配配置项,没有跟踪字段的完整嵌套路径。当处理bar对象下的baz字段时,key是baz,而配置里的键是bar.baz,无法匹配,导致该字段未被标记为需要保留浮点数格式。

修改后的代码

核心修改是在replacer函数中跟踪当前字段的完整路径,用路径字符串匹配配置项:

const stringifyWithFloats = (config = {}, decimals = 1) => {
  const beginFloat = '__FLOAT__BEGIN__';
  const endFloat = '__FLOAT__END__';

  return (inputValue, inputReplacer, space) => {
    const inputReplacerIsFunction = typeof inputReplacer === "function";
    // 跟踪当前字段的完整路径,用数组存储层级key
    const currentPath = [];

    const jsonReplacer = (key, val) => {
      // 处理根对象的初始调用(key为空字符串)
      if (key !== '') {
        currentPath.push(key);
      }

      let value;
      if (inputReplacerIsFunction) {
        value = inputReplacer(key, val);
      } else if (Array.isArray(inputReplacer)) {
        value = inputReplacer.indexOf(key) !== -1 ? val : undefined;
      } else {
        value = val;
      }

      // 生成完整路径字符串:用.连接层级key
      const fullPath = currentPath.join('.');
      // 匹配配置:当前key或完整路径是否在config中
      const forceFloat = 
        (config[key] === "float" || config[fullPath] === "float") &&
        (value || value === 0) &&
        typeof value === "number" &&
        !value.toString().toLowerCase().includes("e");

      const result = forceFloat ? `${beginFloat}${value}${endFloat}` : value;

      // 退出当前层级时移除路径中的key
      if (key !== '') {
        currentPath.pop();
      }
      return result;
    };

    const json = JSON.stringify(inputValue, jsonReplacer, space);

    const regexReplacer = (match, num) => {
      return num.includes(".") || Number.isNaN(num)
        ? Number.isNaN(num)
          ? num
          : Number(num).toFixed(decimals)
        : `${num}.${"0".repeat(decimals)}`;
    };

    const re = new RegExp(`"${beginFloat}(.+?)${endFloat}"`, "g");
    return json.replace(re, regexReplacer);
  };
};

测试验证

使用原测试输入,配置嵌套路径:

// Test input
const testInput = {
  foo: 10.0,
  bar: {
    baz: 20.0,
    qux: {
      value: 30.0
    }
  }
};

// Configure nested paths
const customStringify = stringifyWithFloats({ 
  foo: 'float', 
  'bar.baz': 'float',
  'bar.qux.value': 'float' 
});

// Serialize
const serializedJson = customStringify(testInput, null, 2);

console.log(serializedJson);

输出结果:

{
  "foo": 10.0,
  "bar": {
    "baz": 20.0,
    "qux": {
      "value": 30.0
    }
  }
}

所有指定的嵌套字段都成功保留了浮点数格式。

关键修改说明

  1. 路径跟踪:用currentPath数组存储当前遍历的层级key,进入字段时push,退出时pop,确保路径正确对应当前遍历的层级。
  2. 完整路径匹配:生成fullPath字符串(如bar.baz),同时支持匹配当前层级key(兼容原顶层字段配置)和完整嵌套路径。
  3. 根对象处理:跳过根对象的空字符串key,避免路径生成异常。

内容的提问来源于stack exchange,提问作者Feel free

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:20:54