字符串转换整数 (atoi)

从字符串里提取有效数,大于2^31 − 1 返回 2^31 − 1,小于−2^31,返回−2 ^ 31。

输入: "42"
输出: 42
输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
输入: "   +42"
输出: 42
输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。

最初的解法

var myAtoi = function(str) {
    let result = +(str.trim().match(/^[-+]?\d+/g) || [])[0];
    if(result){
        if(result > 2**31 - 1){
            return 2**31 - 1;
        }
        else if(result < -(2**31)){
            return -(2**31);
        }
        return result;
    }
    
    return 0;
};

match 函数可能返回null

+null 会返回 0

-(2**31) 的()不加会报一个晦涩的语法错误,大概是造成了代码执行的二意性。

Uncaught SyntaxError: Unary operator used immediately before exponentiation expression. Parenthesis must be used to disambiguate operator precedence
上面的问题在于用了太多的判断,其实parseInt函数可以很好的起到过滤作用,但我认为用正则起到很好的锻炼作用

参考后的解法

var myAtoi = function(str) {
      let number = +parseInt(str);
      let result = number
        ? Math.max(Math.min(number, 2 ** 31 - 1), -(2 ** 31))
        : 0;
      return result;
    };

parseInt 可能返回 NaN,而Boolean(NaN) 返回false

这也意味着 逻辑进入Math.max(Math.min()) 后,result不会时NaN

问题

您会觉得 Math.max(Math.min()) 这种写法不易读吗?

有趣的事

最初的解法是有let isNumber = !Number.isNaN(result); 这段代码,我以为+null 会返回 NaNBoolean(NaN) 返回false,然后删掉了这行代码,结果发现+null 会返回 0,写文章的过程中,认知发生了两次变化。

你可能感兴趣的:(字符串转换整数 (atoi))