题目
假设传入的参数就是“2时5分”、“3时46秒”这种格式的字符串,省去参数类型检测。
略去检测分秒数大于 60 的情况。
思路:
- 先把字符串 split 打散转换为数组
- forEach() 遍历数组元素
- 找出“时”、“分”等关键词的 index
- 据此切分拼接新格式数组
注意点:
- arguments 和对应参数的绑定
- 非严格模式下,当传入实参,实参和 arguments 的值会共享(一改都变)
- 所以,注一 处需要先保存 arguments[0] 的值,再进行参数的修改。如果线修改了第一个参数,由于绑定效应,arguments[0] 的值被篡改而丢失。
代码实现:
// 格式转换函数
function transfer(str) {
// 字符串转数组
let arr = str.split("");
let hour, min, sec, secIndex, minIndex, hourIndex;
// 遍历获取切分位置
arr.forEach((item, index) => {
if (item === "时") hourIndex = index;
if (item === "分") minIndex = index;
if (item === "秒") secIndex = index;
});
// 处理缺少某个时间单位时的特殊情况
hour = getNumber(str, hourIndex);
min = hourIndex
? getNumber(str, hourIndex, minIndex)
: getNumber(str, minIndex);
if (minIndex) {
sec = getNumber(str, minIndex, secIndex);
} else if (hourIndex) {
sec = getNumber(str, hourIndex, secIndex);
} else {
sec = getNumber(str, secIndex);
}
// 拼接最后的结果
let result = `${hour}:${min}:${sec}`;
return result;
}
// 切分时间段数字的函数
function getNumber(str, preIndex, nextIndex) {
if (arguments.length === 2) {
// preIndex = -1; 注一
nextIndex = arguments[1];
preIndex = -1;
}
if (!nextIndex) {
time = "00";
} else {
let diff = nextIndex - preIndex;
// 考虑数字为个位数时的情况
time =
diff > 2
? str.slice(preIndex + 1, nextIndex)
: `0${str.slice(preIndex + 1, nextIndex)}`;
}
return time;
}
结果输出
console.log(transfer('2时2分2秒'));
console.log(transfer("2时2分"));
console.log(transfer("2时2秒"));
console.log(transfer("2分2秒"));
console.log(transfer("2时"));
console.log(transfer("2分"));
console.log(transfer("2秒"));
console.log(transfer(""));
02:02:02
02:02:00
02:00:02
00:02:02
02:00:00
00:02:00
00:00:02
00:00:00
涉及到的知识
- 字符串转数组 .split() 参数为分隔符。
- 当无参数,将全部内容作为唯一数组元素。
- 当参数为空字符串,会将全部内容打散作为数组元素
- substr()
- 第一个参数 起始位置 前闭
- 当第一个参数为负,与 length 相加
- 第二个参数 截取的个数
- 第二个参数为负,将其转为 0
- 第一个参数 起始位置 前闭
- substring()
- 两个参数 前闭后开
- 当第二个参数空缺,切到尾
- 当参数为负,将其转为 0
- 该方法会将较小的数作为开始位置
slice()
- 两个参数 前闭后开
- 当第二个参数空缺,切到尾
- 当参数为负,与 length 相加
非严格模式,当有实参传入,arguments 对象与实参会形成绑定