我在json中有一些数字溢出了Number类型,所以我希望它是bigint,但是怎么做呢?
{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}
mrfwxfqh1#
您可以使用JSON.parse()reviver 参数
JSON.parse()
要以这种方式控制JSON.parse()的行为,可以使用JSON.parse(reviver)的第二个参数-预处理键值对的函数(可能会将所需的值传递给BigInt())。然而,被识别为数字的值仍然会被“强制”(指出这个问题的功劳归于@YohanesGultom)。为了解决这个问题,您可以在源JSON字符串中引用 big numbers(将它们转换为字符串),以便在转换为bigint时保留它们的值。只要你只想将某些数字转换为bigint,你就需要选择适当的标准(例如,检查值是否超过Number.MAX_SAFE_INTEGER与Number.isSafeInteger(),正如@PeterSeliger所建议的那样)。因此,您的问题可能会通过以下方式解决:
JSON.parse
reviver
BigInt()
bigint
Number.MAX_SAFE_INTEGER
Number.isSafeInteger()
// source JSON string const input = `{"foo":[[0],[64],[89],[97]],"bar":[[2323866757078990912,144636906343245838,441695983932742154,163402272522524744],[2477006750808014916,78818525534420994],[18577623609266200],[9008333127155712]]}` // function that implements desired criteria // to separate *big numbers* from *small* ones // // (works for input parameter num of type number/string) const isBigNumber = num => !Number.isSafeInteger(+num) // function that enquotes *big numbers* matching // desired criteria into double quotes inside // JSON string // // (function checking for *big numbers* may be // passed as a second parameter for flexibility) const enquoteBigNumber = (jsonString, bigNumChecker) => jsonString .replaceAll( /([:\s\[,]*)(\d+)([\s,\]]*)/g, (matchingSubstr, prefix, bigNum, suffix) => bigNumChecker(bigNum) ? `${prefix}"${bigNum}"${suffix}` : matchingSubstr ) // parser that turns matching *big numbers* in // source JSON string to bigint const parseWithBigInt = (jsonString, bigNumChecker) => JSON.parse( enquoteBigNumber(jsonString, bigNumChecker), (key, value) => !isNaN(value) && bigNumChecker(value) ? BigInt(value) : value ) // resulting output const output = parseWithBigInt(input, isBigNumber) console.log("output.foo[1][0]: \n", output.foo[1][0], `(type: ${typeof output.foo[1][0]})`) console.log("output.bar[0][0]: \n", output.bar[0][0].toString(), `(type: ${typeof output.bar[0][0]})`)
.as-console-wrapper{min-height: 100% !important;}
***注意:***你可能会发现RegExp模式在JSON值中匹配数字字符串不是很健壮,所以你可以随意提出你的(因为我的是我最快的,我设法从我的头顶上拿起演示目的)***注意:***您仍然可以选择使用某些库,正如@YohanesGultom所建议的那样,但将10k添加到您的客户端捆绑包或将37k添加到您的服务器端依赖项(可能是docker镜像大小)可能并不十分合理。
1条答案
按热度按时间mrfwxfqh1#
TLDR;
您可以使用
JSON.parse()
reviver 参数详细解决方案
要以这种方式控制
JSON.parse()
的行为,可以使用JSON.parse
(reviver
)的第二个参数-预处理键值对的函数(可能会将所需的值传递给BigInt()
)。然而,被识别为数字的值仍然会被“强制”(指出这个问题的功劳归于@YohanesGultom)。
为了解决这个问题,您可以在源JSON字符串中引用 big numbers(将它们转换为字符串),以便在转换为
bigint
时保留它们的值。只要你只想将某些数字转换为
bigint
,你就需要选择适当的标准(例如,检查值是否超过Number.MAX_SAFE_INTEGER
与Number.isSafeInteger()
,正如@PeterSeliger所建议的那样)。因此,您的问题可能会通过以下方式解决:
***注意:***你可能会发现RegExp模式在JSON值中匹配数字字符串不是很健壮,所以你可以随意提出你的(因为我的是我最快的,我设法从我的头顶上拿起演示目的)
***注意:***您仍然可以选择使用某些库,正如@YohanesGultom所建议的那样,但将10k添加到您的客户端捆绑包或将37k添加到您的服务器端依赖项(可能是docker镜像大小)可能并不十分合理。