javascript JSON将对象属性直接解析为int
我有一些使用本机浏览器实现从json解析的对象。对象的某些属性是数字。目前,数字是从json解析为字符串的,我使用parseInt将字符串转换为我需要的intjavascript JSON将对象属性直接解析为int,javascript,Javascript,我有一些使用本机浏览器实现从json解析的对象。对象的某些属性是数字。目前,数字是从json解析为字符串的,我使用parseInt将字符串转换为我需要的int 问题是,我使用了23个对象,总共有大约80个属性解析为int,如下所示: if (TheObject && TheObject.TheProperty) { TheObject.TheProperty = parseInt(TheObject.TheProperty, 10); } function intify(
问题是,我使用了23个对象,总共有大约80个属性解析为int,如下所示:
if (TheObject && TheObject.TheProperty) {
TheObject.TheProperty = parseInt(TheObject.TheProperty, 10);
}
function intify(obj, fields) {
if (typeof(obj) == "undefined") return;
var numFields = fields.length;
for (var i = 0; i < numFields; i++) {
var field = fields[i];
if (typeof(obj[field]) != "undefined") {
obj[field] = parseInt(obj[field], 10);
}
}
return obj;
}
intify(obj, ['foo', 'bar']);
intify(obj.baz, ['boo']);
有许多代码行看起来非常相似。是否有一种方法可以使用原型或其他东西来更改JSON.parse函数的工作方式,以便每次解析器运行时都检查字符串属性是否为int,如果是,则直接将其转换为int
谢谢。JSON可以按如下方式处理数字:
{
"TheObject":{
"TheProperty":5
}
}
如果您的属性是双引号,则它是一个字符串,否则它是一个数字、布尔值(true
和false
值)、null
或导致分析错误的内容
请参见我认为您无法修改解析器,但可以使用一个属性数组,并使用
[]
符号在parseInt()
循环中访问它们,而不是使用许多类似的代码行。当然,如果您有权访问生成JSON的代码,那么将其更改为正确无引号的输出整数就更容易了
// Array of properties you want to parse out
var parseUs = ['prop1','prop2','prop3','prop4'];
// Array of objects you need to parse them in
var objs = [obj1, obj2, obj3];
// Iterate over the objects
for (var i=0; i<objs.length; i++) {
// And over the properties array
for (var j=0; j<parseUs.length; j++) {
// Parse out the int value if the object has the property
if (objs[i].hasOwnProperty(parseUs[j]) {
objs[i][parseUs[j]] = parseInt(parseUs[j], 10);
}
}
}
//要解析的属性数组
var parseUs=['prop1'、'prop2'、'prop3'、'prop4'];
//需要在其中解析它们的对象数组
变量objs=[obj1、obj2、obj3];
//迭代对象
for(var i=0;i@kbec给出了正确的答案。如果您无法控制数据源,则可以使用以下方法:
if (TheObject && TheObject.TheProperty) {
TheObject.TheProperty = parseInt(TheObject.TheProperty, 10);
}
function intify(obj, fields) {
if (typeof(obj) == "undefined") return;
var numFields = fields.length;
for (var i = 0; i < numFields; i++) {
var field = fields[i];
if (typeof(obj[field]) != "undefined") {
obj[field] = parseInt(obj[field], 10);
}
}
return obj;
}
intify(obj, ['foo', 'bar']);
intify(obj.baz, ['boo']);
函数初始化(对象,字段){
if(typeof(obj)=“未定义”)返回;
var numFields=fields.length;
对于(变量i=0;iJSON.parse
接受函数形式的第二个参数,该函数可以进行一些后期处理
JSON.parse('{"p": "5"}', function(k, v) {
return (typeof v === "object" || isNaN(v)) ? v : parseInt(v, 10);
});
如果您不想处理所有数字字符串,那么就创建一个查找表,列出您想要的属性
var props = {"p":1, "some_prop":1, "another_prop":1};
JSON.parse('{"p": "5"}', function(k, v) {
return props.hasOwnProperty(k) ? parseInt(v, 10) : v;
});
如果无法固定数据源(数字应以数字而不是字符串的形式传递),它将在处理每个项目时接收该项目。这使您可以选择转换它:
// Create this once
var propsToConvert = {
TheProperty: 1,
TheOtherProperty: 1,
YetAnotherProperty: 1,
// ...and so on...
};
// Use it each time you parse
var obj = JSON.parse(str, function(key, value) {
if (propsToConvert.hasOwnProperty(key)) {
return parseInt(value, 10);
}
return value;
});
|
或者,如果属性名称不够唯一(property
并不总是需要处理,仅当它是object
的属性时),您可以通过两级检查来执行此操作:
// Define the object names and their property names (once)
var propsToConvert = {
TheObject: {
TheProperty: 1,
TheOtherProperty: 1,
YetAnotherProperty: 1,
// ...and so on...
},
AnotherObject: {
// Other properties...
}
};
// Use it each time you parse
var obj = JSON.parse(str, function(key, value) {
var name, props;
if (typeof value === "object") {
props = propsToConvert[key];
if (props) {
for (name in props) {
value[name] = parseInt(value[name], 10);
}
}
}
});
(恢复器是由内而外调用的,因此当您看到对象的关键点时,属性将位于对象上;这就是为什么我们在适当的位置更新它们。)
你明白了,你可以用复活器功能做很多事情
旁注:parseInt
,我在上面使用过,它相当宽容——可能比你想要的更宽容。例如:
var a = parseInt('1a', 10); // 1, instead of NaN
如果您同意将“0x10”
等字符串视为十六进制,那么:
var a = Number(str);
…这将为无效的数字字符串(number(“1a”)
为NaN
)提供NaN
)。由于JSON并不意味着有十六进制数,如果您确定损坏的数据源不会将其编码为十六进制,那么您就是黄金
否则,如果您需要十进制,但希望严格,则需要对字符串执行正则表达式,以确保它与有效十进制数的模式匹配(如果您希望支持JavaScript数字文本支持的所有内容,这相当复杂)。如果parseInt('1a',10),您将如何自动执行该操作;
返回1
?但无论如何,即使属性看起来像一个数字——这并不意味着它是数字在我运行parseInt函数的情况下,我知道它是一个数字。对于属性可能是数字但也可能是1a的情况,您需要使用jquery的IsNumeric函数。如果数字字符串与数字一致ng到源代码,然后你可以转换,否则就不能。JSON.parse
可以以本机方式处理此问题,但最好首先将它们作为数字发送。这是不可能的吗?好的,谢谢大家的回答。我将记住用于其他目的的Revivier函数。同时,我正在重新编写一些服务器序列化n个实现。如果手动转换为int,则可以使用parseInt(obj[field],10);
此选项:parseInt(obj[field],10)| | 0
。使用此选项,您可以确保属性是一个数字,即使它们的值是NaN(不是数字)你只得到了0
@kbec:意见和具体用例的问题。然而,一般来说,我宁愿收到NaN
而不是0
,因为它不是一个数字,但应该是。把它作为0
扫到地毯下可能会导致一些痛苦的调试过程。@kbec:是的,但你会隐藏f假装本来应该是数字的东西不是。@Amadan:parseInt的问题在于它太宽容了。parseInt('1a',10)
是1
。@Amadan:是的,这都是关于选择的。(完全是一个附带问题。)“我认为你无法修改解析器…”不需要,这就是reviver函数的用途。您不能修改解析器。这只是内置浏览器解析器的本机代码。您可以编写自己的解析器,但这一切都是为了什么?问题是,有些东西可能通过了isNaN
检查,但仍然不是数字:{“name”:“Johnny Wonten”,“login”:“1.10”,描述:“十分之一,geddit!?!11!”
@Amadan:这只是一个测试的示例。OP可以针对属性的查找表进行测试。虽然我不太清楚您的意思。您的示例中哪项不应该通过。在示例中,login
仍然应该是一个字符串;它看起来像是一个巧合