在 JavaScript 中将整个字符串转换为整数

发布于 2024-10-02 03:56:02 字数 1190 浏览 3 评论 0原文

我最近遇到了一段与此非常相似的代码:

var nHours = parseInt(txtHours);
if( isNaN(nHours))  // Do something
else // Do something else with the value

编写此代码的开发人员的印象是 nHours 要么是与 txtHours 完全匹配的整数,要么是NaN。这个假设有几个问题。

首先,开发人员保留了基数参数,这意味着输入 "09" 将得到 0 值,而不是 9。这个问题可以通过添加基数来解决,如下所示:

var nHours = parseInt(txtHours,10);
if( isNaN(nHours))  // Do something
else // Do something else with the value

接下来,输入 "1.5" 将得到 1 值,而不是 NaN > 这不是开发人员所期望的,因为 1.5 不是整数。同样,"1a" 值将生成 1 值,而不是 NaN

所有这些问题在某种程度上都是可以理解的,因为这是如何将字符串转换为整数的最常见示例之一,并且大多数地方不讨论这些情况。

无论如何,这让我想到我不知道有任何内置方法可以获取这样的整数。有 Number(txtHours) (或 +txtHours),它更接近,但接受非整数,并将处理 null” " 为 0,而不是 NaN

为了帮助开发人员解决问题,我提供了以下功能:

function ConvertToInteger(text)
{
    var number = Math.floor(+text);
    return text && number == text ? number : NaN;
}

这似乎涵盖了上述所有问题。有谁知道这种技术有什么问题或者可能有更简单的方法来获得相同的结果?

I recently ran into a piece of code very much like this one:

var nHours = parseInt(txtHours);
if( isNaN(nHours))  // Do something
else // Do something else with the value

The developer who wrote this code was under the impression that nHours would either be an integer that exactly matched txtHours or NaN. There are several things wrong with this assumption.

First, the developer left of the radix argument which means input of "09" would result in a value of 0 instead of 9. This issue can be resolved by adding the radix in like so:

var nHours = parseInt(txtHours,10);
if( isNaN(nHours))  // Do something
else // Do something else with the value

Next, input of "1.5" will result in a value of 1 instead of NaN which is not what the developer expected since 1.5 is not an integer. Likewise a value of "1a" will result in a value of 1 instead of NaN.

All of these issues are somewhat understandable since this is one of the most common examples of how to convert a string to an integer and most places don't discuss these cases.

At any rate it got me thinking that I'm not aware of any built in way to get an integer like this. There is Number(txtHours) (or +txtHours) which comes closer but accepts non-integer numbers and will treat null and "" as 0 instead of NaN.

To help the developer out I provided the following function:

function ConvertToInteger(text)
{
    var number = Math.floor(+text);
    return text && number == text ? number : NaN;
}

This seems to cover all the above issues. Does anyone know of anything wrong with this technique or maybe a simpler way to get the same results?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

舂唻埖巳落 2024-10-09 03:56:02

在这里,这就是我想到的:(

function integer(x) {
    if (typeof x !== "number" && typeof x !== "string" || x === "") {
        return NaN;
    } else {
        x = Number(x);
        return x === Math.floor(x) ? x : NaN;
    }
}

注意:我更新了这个函数以防止空格字符串。见下文。)

这个想法是只接受类型为 Number 或 String 的参数(但不接受空字符串值) 。然后完成到 Number 的转换(如果它是字符串),最后将其值与 Floor() 值进行比较,以确定该数字是否为整数。

integer(); // NaN
integer(""); // NaN
integer(null); // NaN
integer(true); // NaN
integer(false); // NaN
integer("1a"); // NaN
integer("1.3"); // NaN
integer(1.3); // NaN    
integer(7); // 7

然而,NaN 值在这里被“误用”,因为浮点数和表示浮点数的字符串会导致 NaN,而这在技术上是不正确的。

另请注意,由于字符串转换为数字的方式,字符串参数可能有尾随或前导空格,或前导零:

integer("   3   "); // 3    
integer("0003"); // 3

另一种方法...

如果输入值是字符串,则可以使用正则表达式。
此正则表达式:/^\s*(\+|-)?\d+\s*$/ 将匹配表示整数的字符串。

更新函数!

function integer(x) {
    if ( typeof x === "string" && /^\s*(\+|-)?\d+\s*$/.test(x) ) {
        x = Number(x);
    }
    if ( typeof x === "number" ) {
        return x === Math.floor(x) ? x : NaN;
    }
    return NaN;
}

这个版本的integer()更加严格,因为它只允许遵循特定模式的字符串(使用正则表达式进行测试)。它产生与其他integer()函数相同的结果,除了它另外忽略所有空白字符串(正如@CMS所指出的)。

再次更新!

我注意到@Zecc的答案并稍微简化了代码...我想这也有效:

function integer(x) {
    if( /^\s*(\+|-)?\d+\s*$/.test(String(x)) ){
        return parseInt(x, 10);
    }
    return Number.NaN;
}  

它可能不是最快的解决方案(就性能),但我喜欢它的简单性:)

Here, that's what I came up with:

function integer(x) {
    if (typeof x !== "number" && typeof x !== "string" || x === "") {
        return NaN;
    } else {
        x = Number(x);
        return x === Math.floor(x) ? x : NaN;
    }
}

(Note: I updated this function to saveguard against white-space strings. See below.)

The idea is to only accept arguments which type is either Number or String (but not the empty string value). Then a conversion to Number is done (in case it was a string), and finally its value is compared to the floor() value to determine if the number is a integer or not.

integer(); // NaN
integer(""); // NaN
integer(null); // NaN
integer(true); // NaN
integer(false); // NaN
integer("1a"); // NaN
integer("1.3"); // NaN
integer(1.3); // NaN    
integer(7); // 7

However, the NaN value is "misused" here, since floats and strings representing floats result in NaN, and that is technically not true.

Also, note that because of the way strings are converted into numbers, the string argument may have trailing or leading white-space, or leading zeroes:

integer("   3   "); // 3    
integer("0003"); // 3

Another approach...

You can use a regular expression if the input value is a string.
This regexp: /^\s*(\+|-)?\d+\s*$/ will match strings that represent integers.

UPDATED FUNCTION!

function integer(x) {
    if ( typeof x === "string" && /^\s*(\+|-)?\d+\s*$/.test(x) ) {
        x = Number(x);
    }
    if ( typeof x === "number" ) {
        return x === Math.floor(x) ? x : NaN;
    }
    return NaN;
}

This version of integer() is more strict as it allows only strings that follow a certain pattern (which is tested with a regexp). It produces the same results as the other integer() function, except that it additionally disregards all white-space strings (as pointed out by @CMS).

Updated again!

I noticed @Zecc's answer and simplified the code a bit... I guess this works, too:

function integer(x) {
    if( /^\s*(\+|-)?\d+\s*$/.test(String(x)) ){
        return parseInt(x, 10);
    }
    return Number.NaN;
}  

It probaly isn't the fastest solution (in terms of performance), but I like its simplicity :)

长梦不多时 2024-10-09 03:56:02

这是我的尝试:

function integer(x) {
    var n = parseFloat(x); // No need to check typeof x; parseFloat does it for us
    if(!isNaN(n) && /^\s*(\+|-)?\d+\s*$/.test(String(x))){
        return n;
    }
    return Number.NaN;
}

我必须将正则表达式归功于 Šime Vidas,尽管我自己会做到这一点。

编辑:我不知道有一个NaN全局。我一直使用 Number.NaN
生活和学习。

Here's my attempt:

function integer(x) {
    var n = parseFloat(x); // No need to check typeof x; parseFloat does it for us
    if(!isNaN(n) && /^\s*(\+|-)?\d+\s*$/.test(String(x))){
        return n;
    }
    return Number.NaN;
}

I have to credit Šime Vidas for the regex, though I would get there myself.

Edit: I wasn't aware there was a NaN global. I've always used Number.NaN.
Live and learn.

木森分化 2024-10-09 03:56:02

我的解决方案涉及一些廉价的技巧。它基于 JavaScript 中的位运算符将其操作数转换为整数的事实。

我不太确定代表整数的字符串是否应该工作,所以这里有两种不同的解决方案。

function integer (number) { 
  return ~~number == number ? ~~number : NaN; 
}

function integer (number) {
  return ~~number === number ? ~~number : NaN;
}

第一个将两个整数作为字符串使用,第二个则不会。
按位非 (~) 运算符会将其操作数转换为整数。
对于无法用 32 位宽整数表示形式表示的较大整数(-2147483647 .. 2147483647),此方法会失败。

My Solution involves some cheap trick. It based on the fact that bit operators in Javascript convert their operands to integers.

I wasn't quite sure if strings representing integers should work so here are two different solutions.

function integer (number) { 
  return ~~number == number ? ~~number : NaN; 
}

function integer (number) {
  return ~~number === number ? ~~number : NaN;
}

The first one will work with both integers as strings, the second one won't.
The bitwise not (~) operator will convert its operand to an integer.
This method fails for integers bigger which can't be represented by the 32bit wide representation of integers (-2147483647 .. 2147483647).

涫野音 2024-10-09 03:56:02

您可以先将字符串转换为整数,然后再次转换回字符串。然后检查第一个和第二个字符串是否匹配。

编辑:我的意思的一个例子:

function cs (stringInt) {
    var trimmed = stringInt.trim();     // trim original string
    var num = parseInt(trimmed, 10);    // convert string to integer
    newString = num + "";               // convert newly created integer back to string
    console.log(newString);             // (works in at least Firefox and Chrome) check what's new string like
    return (newString == trimmed);      // if they are identical, you can be sure that original string is an integer
}

如果您输入的字符串确实是整数,则此函数将返回 true。如果不想修剪的话可以修改。使用前导零将会失败,但是,如果您愿意,您可以再次在此函数中删除它们。这样,您无需使用 NaN 或正则表达式,即可轻松检查字符串化整数的有效性。

You can first convert a String to an Integer, and then back to a String again. Then check if first and second strings match.

Edit: an example of what I meant:

function cs (stringInt) {
    var trimmed = stringInt.trim();     // trim original string
    var num = parseInt(trimmed, 10);    // convert string to integer
    newString = num + "";               // convert newly created integer back to string
    console.log(newString);             // (works in at least Firefox and Chrome) check what's new string like
    return (newString == trimmed);      // if they are identical, you can be sure that original string is an integer
}

This function will return true if a string you put in is really an integer. It can be modified if you don't want trimming. Using leading zeroes will fail, but, once again, you can get rid of them in this function if you want. This way, you don't need to mess around with NaN or regex, you can easily check validity of your stringified integer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文