持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
1、数值转字符串遍历拼接
实现思路
- 数字转字符串,字符串按照 '. '进行分隔(因为有可能是小数)
- 整数部分变为字符串数组并进行倒叙
- 遍历该数组,每3位添加一个逗号
- 拼接整数部分与小数部分
// 1938765432.71 -> 1,938,765,432.71
function format_with_array(number) {
// 将数字分隔成整数部分与小数部分 [1938765432, 71]
const arr = (number + "").split(".");
// 将整数部分的数字分割成字符串数组
// 1938765432 -> ['1','9','3','8','7','6','5','4','3','2']
const ints = arr[0].split("");
// 小数部分
const fraction = arr[1] || "";
let result = "";
ints.reverse().forEach((val, i) => {
// 非第一位并且是位值是3的倍数添加 ","
// 依次是 2 + '' 、3 + '2' 、4 + '32'、5 + ','+ '432'...
if (i !== 0 && i % 3 === 0) {
result = val + "," + result;
} else {
result = val + result;
}
});
// 1,938,765,432 + '.' + 71 -> 1,938,765,432.71
return result + (!!fraction ? "." + fraction : "");
}
console.log(format_with_array(1938765432.71));
2、字符串+substring截取
实现思路
- 数字转字符串,并按照'.'分隔
- 整数部分对3求模,获取多余的部分
- 按照长度3进行截取,并添加','
- 拼接整数部分与小数部分
function format_with_substring(number) {
// 分隔整数部分与小数部分
const arr = (number + "").split(".");
// 取出整数部分的字符串,方便通过substring进行截取
const int = arr[0];
// 取出小数部分以便最后进行拼接
const fraction = arr[1] || "";
// 获取多余位数,有可能是0
const more = int.length % 3;
// 截取出多余出来的字符串,如果more是0则此时截取出来的result为空字符串
let result = int.substring(0, more);
for (let i = 0; i < Math.floor(int.length / 3); i++) {
// 每次循环需要从多余位数后面开始截取3个并追加逗号
result += "," + int.substring(more + i * 3, more + (i + 1) * 3);
}
// 如果多余出来0个数字,那么需要去除开头多拼接的逗号
if (more === 0) {
result = result.substring(1);
}
return result + (!!fraction ? "." + fraction : "");
}
console.log(format_with_substring(1938765432.71)); // 1,938,765,432.71
3、除法 + 求模
实现思路
- 数值对1000进行求模,获得最高三位
- 值除以1000,将值是否大于1作为判定是否结束的条件
- 重复1、2步骤
- 拼接整数部分与小数部分
function format_with_mod(number) {
let n = number;
let result = "";
let temp;
do {
// 求模的值,用于获取高三位,这里可能有小数
mod = n % 1000;
// 值是不是大于1,是继续的条件
n = n / 1000;
// 由于可能为小数,所以要通过~~变为整数
temp = ~~mod;
// 要注意这里要对temp进行填充,比如1002取模后,temp为2,此时要填充为002
// 不进行填充的话1002最后会变成1,2而不是1,002
result =
(n >= 1 ? `${temp}`.padStart(3, "0") : temp) +
(!!result ? "," + result : "");
} while (n >= 1);
const strNumber = number + "";
const index = strNumber.indexOf(".");
// 拼接小数部分,
if (index >= 0) {
result += strNumber.substring(index);
}
return result;
}
console.log(format_with_mod(1002)); // 1,002
4、正则表达式
正则表达式中的先行断言、后行断言、正向否定查找与反向否定查找:
名称 | 表达式 | 作用 |
---|---|---|
先行断言(前瞻) | exp1(?=exp2) | 查找exp2前面的exp1 |
后行断言(后顾) | (?<=exp2)exp1 | 查找exp2后面的exp1 |
正向否定查找(负前瞻) | exp1(?!exp2) | 查找后面不是exp2的exp1 |
反向否定查找(负后顾) | (?<!exp2)exp1 | 查找前面不是exp2的exp1 |
(更多正则表达式有关知识详见文章:正则表达式)
实现思路
利用正则表达式的先行断言,去匹配每3个数字为一组的前面的数字,在所匹配内容后面加上','逗号
function format_with_regex(number) {
const reg = /\d{1,3}(?=(\d{3})+$)/g;
const arr = (number + "").split(".");
const fraction = arr[1] || "";
// $&表示匹配到的每组内容
let result = arr[0].replace(reg, '$&,');
return fraction ? result + "." + fraction : result;
}
// replace第二个参数也可以传入一个回调函数,其中回调函数第一个参数表示匹配到的内容
function format_with_regex2(number) {
const reg = /\d{1,3}(?=(\d{3})+$)/g;
const arr = (number + "").split(".");
const fraction = arr[1] || "";
let result = arr[0].replace(reg, function (match) {
return match + ",";
});
return fraction ? result + "." + fraction : result;
}