【问题标题】:Convert an entire String into an Integer in JavaScript在 JavaScript 中将整个字符串转换为整数
【发布时间】:2011-05-09 06:37:24
【问题描述】:

我最近遇到了一段很像这样的代码:

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

编写此代码的开发人员认为nHours 可能是与txtHoursNaN 完全匹配的整数。这个假设有几个问题。

首先,radix 参数左侧的开发人员表示"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;
}

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

【问题讨论】:

  • Number(txtHours) 而不是 number(txtHours)
  • 另外,还有一个约定是构造函数名大写,常规函数名不大写。我建议通过使用像convertToIntegertoInteger 这样的小写名称来遵守该约定。除此之外,该功能对我来说看起来很可靠。
  • ConvertToInteger(true) 返回1,我认为这不是我们想要的行为。
  • 似乎在这些值进入系统时进行一些输入验证可能是一种值得的方法。

标签: javascript string integer


【解决方案1】:

这就是我想出的:

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 的转换(如果它是一个字符串),最后将它的值与 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;
}  

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

【讨论】:

  • @CMS 哦,真是一团糟 :) 正则表达式检查可以解决这个问题。
  • 我知道使用 NaN 是误用,但它似乎是一种表示非整数的好方法。毕竟没有NaI。我可以做几件事,包括使用 null、未定义、一个对象或多个函数,但 NaN 是原始代码所要寻找的,而且它似乎很清楚,可以继续使用它。
  • 当我看到这个时,我的第一个想法是使用正则表达式,但对于我认为应该非常简单的东西来说,这似乎有点矫枉过正。如果我们愿意,我们可以通过修剪输入(如果它是一个字符串)来避免它。
  • @drs9222 是的,NaN 值对于这种情况来说已经足够好了。特别是由于有一个 isNaN() 函数,因此您可以轻松测试返回值以确定输入是否为有效整数。 x = integer(input); if ( !isNaN(x) ) { /* process the input */ } else { /* alert user that input is invalid */ }
  • @drs9222 是的,修剪字符串是个好主意。 trim() 方法可以完成这项工作,但它没有在 IE8 及更低版本中实现,因此应该为这些浏览器定义自定义的 trim() 方法(顺便说一句,这是一项简单的任务)。但是,正则表达式非常严格,这使得整个事情更加健壮。
【解决方案2】:

这是我的尝试:

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
生活和学习。

【讨论】:

  • 实际上,使用 Number.NaN 代替 NaN 是一个明智的选择,因为全局变量 NaN 可以被任何其他值( var NaN = "foo" )覆盖,而 Number.NaN 属性不能.
【解决方案3】:

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

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

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

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

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

【讨论】:

    【解决方案4】:

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

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

    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 或正则表达式,您可以轻松检查字符串化整数的有效性。

    【讨论】:

    • @darioo 将字符串转换为整数...如何?方法多种多样。
    • @Šime Vidas:我已经更新了我的答案。我想说 parseInt 仍然是将字符串转换为整数的最佳方法。
    • 我怀疑您是故意这样做的,但是如果将字符串以外的任何内容(包括整数)用作输入,您的示例将失败。它也不返回实际使用的整数。
    • @drs9222:好吧,您确实要求转换字符串的东西,而不是其他东西。您不必完全按照所写的方式使用此功能,您可以自己修改它以满足您的需要。但是,您可以使用它来检查输入的字符串是否真的是整数,然后使用 parseInt 将其转换以供实际使用。我写的更多的是一个实用函数。
    • 我明白这一点,我只是重读了我原来的问题,你说得对,我确实说过字符串。但是,我还特别提到了 null。我想我被我针对我的示例运行的测试和其他可以接受任何输入的答案所抛弃。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多