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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10563864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:54:02  来源:igfitidea点击:

javascript JSON parse object property directly to int

javascript

提问by frenchie

I have some objects that I'm parsing from json using native browser implementations. Some of the objects' properties are numbers. For the moment, the numbers are parse from json as strings and I use parseInt to cast the string to the int I need.

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

The problem is that I've got 23 objects I do this with and overall about 80 properties that I'm parsing to ints like this:

问题是我有 23 个对象,我用它来做这件事,总共有大约 80 个属性,我解析成这样的整数:

if (TheObject && TheObject.TheProperty) {
   TheObject.TheProperty = parseInt(TheObject.TheProperty, 10);
}

There are many lines of code that look very similar. Is there a way using prototypes or something to change the way the JSON.parse function works so that each time the parser runs it checks to see if a string property is actually an int and if so cast it directly as such?

有很多行看起来非常相似的代码。有没有办法使用原型或其他东西来改变 JSON.parse 函数的工作方式,这样每次解析器运行时它都会检查字符串属性是否实际上是一个 int ,如果是这样直接转换它?

Thanks.

谢谢。

采纳答案by kbec

JSON can handle numbers as follow:

JSON 可以处理数字如下:

{
    "TheObject":{
        "TheProperty":5
    }
}

If your property was doublequoted then it's a string else it's a numeric, boolean (trueand falsevalues), nullor just something that cause parse error.

如果您的属性是双引号,那么它是一个字符串,否则它是一个数字、布尔值(truefalse值),null或者只是导致解析错误的东西。

See http://json.org/

http://json.org/

回答by cliffs of insanity

JSON.parseaccepts a second argument in the form of a function that can do some post processing.

JSON.parse以函数形式接受第二个参数,该函数可以进行一些后期处理。

JSON.parse('{"p": "5"}', function(k, v) { 
    return (typeof v === "object" || isNaN(v)) ? v : parseInt(v, 10); 
});


I you don't want to process all numeric strings, then create a lookup table of the properties you do want.

我不想处理所有数字字符串,然后创建您想要的属性的查找表。

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; 
});

回答by Michael Berkowski

I don't think you'll be able to modify the parser, but instead of many similar lines of code, use an array of the properties and access them with the []notation in a loop to parseInt()them. Of course, if you have access to the code producing the JSON, it is easier to change it to output ints properly unquoted.

我认为您无法修改解析器,但不要使用许多类似的代码行,而是使用属性数组并使用[]循环中的符号访问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);
    }
  }
}

Note: This won't work if the objects share property names which are not int values in all of them. If that's the case, you would need to modify this to use an array of properties per object.

注意:如果对象共享所有这些对象中都不是 int 值的属性名称,这将不起作用。如果是这种情况,您需要修改它以使用每个对象的属性数组。

回答by T.J. Crowder

If your data source can't be fixed (numbers should be passed as numbers, not as strings), you can pass JSON.parsea "reviver" function, which will receive each item as it's being processed. This gives you the option of transforming it:

如果您的数据源无法固定(数字应该作为数字传递,而不是作为字符串传递JSON.parse),您可以传递一个“reviver”函数,它将在处理每个项目时接收它。这为您提供了转换它的选项:

// 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;
});

Live example| source

活生生的例子| 来源

Or if the property names are not sufficiently unique (ThePropertydoesn't alwaysneed handling, just when it's a property of TheObject), you can do this as a two-level check:

或者,如果属性名称不够独特(TheProperty并不总是需要处理,只是当它是 的属性时TheObject),您可以将其作为两级检查执行:

// 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);
            }
        }
    }
});

(Revivers are called inside-out, so the properties will be on the object by the time you see the object's key; that's why we update them in place.)

(Revivers 被称为由内而外,因此当您看到对象的键时,属性将在对象上;这就是我们就地更新它们的原因。)

You get the idea, there's a lotyou can do with reviver functions.

你明白了,你可以用 reviver 功能做很多事情。



Side note: parseInt, which I've used above, is fairly forgiving — possibly more forgiving than you want. For instance:

旁注:parseInt,我在上面使用过,相当宽容——可能比你想要的更宽容。例如:

var a = parseInt('1a', 10); // 1, instead of NaN

If you're okay with strings like "0x10"being treated as hex, then:

如果您同意将字符串"0x10"视为十六进制,那么:

var a = Number(str);

...which will give you NaNfor invalid number strings (Number("1a")is NaN). Since JSON isn't meant to have hex numbers, if you're sure the broken data source won't encode them as hex, you're golden.

...这将为您NaN提供无效的数字字符串(Number("1a")is NaN)。由于 JSON 并不意味着有十六进制数字,如果您确定损坏的数据源不会将它们编码为十六进制,那么您就是黄金。

Otherwise, if you need decimal but you want to be strict, you'll need to do a regex on the string to make sure it matches the pattern for a valid decimal number (which is fairly complex, if you want to support all the stuff JavaScript numeric literals support).

否则,如果您需要十进制但又想严格,则需要对字符串执行正则表达式以确保它与有效十进制数的模式匹配(这相当复杂,如果您想支持所有内容JavaScript 数字文字支持)。

回答by Amadan

@kbec gives the correct answer. If you don't have control over your data source, then you can use something like this:

@kbec 给出了正确答案。如果您无法控制数据源,则可以使用以下方法:

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']);