javascript JSON将对象属性直接解析为int

javascript JSON将对象属性直接解析为int,javascript,Javascript,我有一些使用本机浏览器实现从json解析的对象。对象的某些属性是数字。目前,数字是从json解析为字符串的,我使用parseInt将字符串转换为我需要的int 问题是,我使用了23个对象,总共有大约80个属性解析为int,如下所示: if (TheObject && TheObject.TheProperty) { TheObject.TheProperty = parseInt(TheObject.TheProperty, 10); } function intify(

我有一些使用本机浏览器实现从json解析的对象。对象的某些属性是数字。目前,数字是从json解析为字符串的,我使用parseInt将字符串转换为我需要的int


问题是,我使用了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;i
JSON.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
仍然应该是一个字符串;它看起来像是一个巧合