使用JSON.stringify时强制浮点值

Liv*_*ner 6 javascript typescript

我想迫使一个号码是一个浮动,JSON.stringify()之后。不幸的是JSON.stringify()删除了1 .0

范例:

JSON.stringify(1.0) // "1"
Run Code Online (Sandbox Code Playgroud)

想要的结果:

JSON.stringify(1.0) // "1.0"
Run Code Online (Sandbox Code Playgroud)

我正在使用一个API,该API需要JSON格式的对象,但它仅能理解十进制值。所以我想问问是否可以使用JSON.stringify生成带有十进制值的字符串而无需使用Regex-.replace-magic

Car*_*gas 6

对您的问题的直接且合理的简短回答是否定的,您无法使用 JSON.stringify 自定义数值的序列化。请参阅MDN 上的 JSON.stringify()

如果您真的需要整数的小数,您必须使用“regex-magic”,正如您在问题中提到的,或者找到一个允许您执行此类技巧的库。如果您不处理过于复杂或多种不同类型的对象,您可能可以手动将它们字符串化。

作为旁注,对于需要使用自定义格式的 JSON 提供的 API,这听起来非常非常可疑。我会三重检查是否还有其他使用方式。


Mac*_*ora 5

使用toFixed而不是stringify。例:

var num = 1;
var numStr = num.toFixed(1); //result is "1.0"
Run Code Online (Sandbox Code Playgroud)

有关toFixed的更多信息-http : //www.w3schools.com/jsref/jsref_tofixed.asp

需要明确的是,我们正在谈论的是转换数字到字符串而不是浮点数(这种类型在javascript中不存在),就像从问题描述中可以理解的那样。toFixed将始终返回具有指定小数位数的String。

  • 我建议使用 MDN 进行参考([`.toFixed()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed))。 (2认同)
  • 将导致`JSON.stringify(1.toFixed(1)) // '"1.0"'`。不是我要找的。不能有引号 (2认同)

Chi*_*shi 4

对于任何想了解正则表达式魔力的人来说,它是:它取自 stringify-with-floats npm 库,但经过修改以支持任何长度的浮点数。

const beginFloat = "~begin~float~";
const endFloat = "~end~float~";

const stringifyWithFloats =
  (config = {}, decimals = 1) =>
  (inputValue, inputReplacer, space) => {
    const inputReplacerIsFunction = typeof inputReplacer === "function";
    let isFirstIteration = true;
    const jsonReplacer = (key, val) => {
      if (isFirstIteration) {
        isFirstIteration = false;
        return inputReplacerIsFunction ? inputReplacer(key, val) : val;
      }
      let value;
      if (inputReplacerIsFunction) {
        value = inputReplacer(key, val);
      } else if (Array.isArray(inputReplacer)) {
        // remove the property if it is not included in the inputReplacer array
        value = inputReplacer.indexOf(key) !== -1 ? val : undefined;
      } else {
        value = val;
      }
      const forceFloat =
        config[key] === "float" &&
        (value || value === 0) &&
        typeof value === "number" &&
        !value.toString().toLowerCase().includes("e");
      return forceFloat ? `${beginFloat}${value}${endFloat}` : value;
    };
    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);
  };

const test = {
  test: "test",
  float: 1.2,
  number: 1,
};

const formatted = stringifyWithFloats(
  { float: "float", number: "float" },
  2
)(test, null, 2); // null and 2 is just for pretty print

console.log(formatted);
Run Code Online (Sandbox Code Playgroud)