题目
手写parseInt
的实现:要求简单一些,把字符串型的数字转化为真正的数字即可,但不能使用JS原生的字符串转数字的API,比如Number()
实现
这道题考察的知识点有下面几个方面:
1 parseInt
的使用
parseInt
接受两个参数,第一个参数s
是要转换的数字或者字符串,第二个参数radix
是指定的转换的基数,介于2
和36
之间
因此需要对两个参数都进行校验,按照题目要求,需要对如果第一个参数不是数字的情况进行处理。
同时需要对radix
进行处理,比如当前radix
为8
,输入为9
,就无法返回正确的数字,因为已经超出了进制转换的范围
同时要注意,parseInt
的使用会从首位开始解析,如果第一位解析成功,第二位解析失败,则返回第一位的解析结果:
parseInt('5f');
// 5
parseInt('15', 2);
// 1
2 charCodeAt
方法
通过charCodeAt
方法返回指定位置的字符的Unicode编码
charAt()
方法执行返回的是指定位置的字符子串。
3 Unicode编码
需要通过判断字符的Unicode编码来将字符串转换位数字,首先看一下常用的ASCII码:
几个关键的字符:
0
的编码是48
,假设当前返回的字符串是'5'
,其Unicode编码是53
, 那么将它转换为数字的话,就需要用其Unicode编码减去48
,结果是5
A
的编码是65
,假设当前返回的字符串是'B'
,其Unicode编码是66
, 那么将它转换为数字的话,就需要用其Unicode编码减去55
,结果是11
a
的编码是97
,假设当前返回的字符串是'b'
,其Unicode编码是98
, 那么将它转换为数字的话,就需要用其Unicode编码减去87
,结果是11
最终的实现:
const parseInt2 = (s, radix = 10) = > {
// 针对输入字符的处理
if (typeof s !== 'string') {
return NaN
}
// radix只能是[2, 32]的正整数
if (typeof radix !== 'number' || radix > 32 || radix < 2 || !/^[0-9]+$/.test(String(radix))) {
return NaN
}
let c;
let result = 0;
for (let i = 0; i < s.length; i++) {
c = s.charCodeAt(i);
if (c >= 97) { // 小写字母a转换为10
c -= 87
} else if (c >= 65) { // 大写字母A转换为10
c -= 55
} else { // 数字直接转换
c -= 48
}
// 超出进制范围
if (c >= radix) {
// 如果第一位就出错返回NaN
if (i === 0) {
return NaN
}
// 非第一位出错,跳出循环,返回已解析的结果
break;
}
// 进位求和
result = (result * radix + c)
}
return result;
};
console.log(parseInt2('5A'));
console.log(parseInt('5A'))
嗯,基础太不扎实了
又尝试了一下使用reduce
代替for循环实现,逻辑是相同的,只不过学到了如何提前结束reduce
的方法,借助修改reduce
遍历函数的第四个参数实现
const parseInt2 = (str, radix = 10) => {
if (typeof str !== 'string') {
return NaN;
}
if (typeof radix !== 'number' || radix > 32 || radix < 2 || !/^\d+$/.test(radix)) {
r
eturn NaN;
}
return [...str].reduce((total, current, currentIndex, array) => {
let charCode = String(current).charCodeAt(0);
if (charCode >= 97) {
charCode -= 87
} else if (charCode >= 65) {
charCode -= 55
} else {
charCode -= 48
}
if (charCode >= radix) {
if (currentIndex === 0) {
return NaN
}
array.splice(currentIndex + 1);
return total
}
total = total * radix + charCode;
return total
}, 0);
};
console.log(parseInt2('5123', 15));
console.log(parseInt('5123', 15))