1,使用数组方法:
1) 数字转字符串,字符串按照小数点.分割
2) 整数部分拆分成字符串数组,并倒叙
3) 遍历, 按照每三位添加逗号,号
4) 拼接整数部分+小数部分
function format_width_array(number) { // 将数字转换为千分位字符串const arr = String(number).split('.');// 整数部分(数组格式) => split将字符串转换为数组const int = arr[0].split('');// 小数点右边的数字部分const float = arr[1] || '';let r = ''// 倒叙并遍历 int.reverse().forEach(function (v, i) {// 非第一位并且是位值是3的倍数, 添加','if (i !== 0 && i % 3 === 0) {r += v + ','}else {// 正常添加字符r += v}})return `${r}${!!float ? '.' + float : ''}`
}
console.log(format_width_array('938765432.02098'))
2.使用字符串的substring截取
1) 数字转字符串,并按照小数点’.’分割
2) 整数部分对3取模,获取余数, 获得substring(0, 余数)的字符串片段r
3) 按照/3截整数商为lenth遍历,每次循环, 字符串片段拼接新的片段: 以下标(余数+i*3)开始, 结束下标在开始下标的基础上加上3
4) 当/3没有余数时, 要去掉字符串首位多出来的逗号','
5) 拼接整数部分+小数部分
// 字符串substring截取:
function format_with_substring(number) {// 数字转字符串并按.分割const arr = String(number).split('.')const int = arr[0] || '';const float = arr[1] || ''// 多余的位数const f = int.length % 3// 获取多余的位数,f可能是0,则r可能是空字符串let r = int.substring(0, f)// 除以3取商, 取整const len = Math.floor(int.length / 3)for (let i = 0; i < len; i++) {r += `,${int.substring(f + i * 3, f + (i + 1) * 3)}`}// 多余的位数if (f === 0) {// 去掉下标0的','r = r.substring(1)}// 整数部分和小数部分拼接return `${r}${!!float ? '.' + float : ''}`
}
console.log(format_with_substring('938765432.02098'))
3.除法+求模
1) 值对1000求模,获得最高三位
2) 值除以1000,值是否大于1判断是否结束
3) 重复1)和2),直到退出
4) 拼接整数部分 + 小数部分
/*** ~是js里的按位取反操作符 , ~~ 就是执行两次按位取反,其实就是保持原值,但是注意虽然是原值,但是对布尔型变量执行这个操作,会转化成相应的数值型变量,也就是
~~true === 1,~~false === 0。 ~~"" == 0 ~~[] == 0padStart和padEnd是类似的用法,padEnd是向后补位,padStart是在前边补位。*/
function format_width_mod(number) {let n = Number(number)let r = ''let temp = null;do {// 求模的值, 用于获取最高三位,这里可能有小数mod = n % 1000;// 值是否大于1,是继续的条件n = n / 1000// 高三位temp = ~~mod; // ~~转化为数值变量// 1. 填充: n>1循环未结束, 就要填充为 比如: 1 => 001,// 不然1 001, 就会变成11,// 2.拼接','r = (n >= 1 ? `${String(temp).padStart(3, '0')}` : temp)+ (!!r ? `,${r}` : '')console.log(r, 'r=====')} while (n >= 1)const strNumber = String(number)const index = strNumber.indexOf('.')// 拼接小数部分if (index >= 0) {r += strNumber.substring(index)}return r
}
console.log(format_width_mod('1001.02098'))
4.正则
1) 利用正则前瞻: exp1(?=exp2) 查找exp2前面的exp1
2) 将整数部分格式化为千分位
3) 拼接整数部分和小数部分
function format_width_regex(number) {const reg = /\d{1,3}(?=(\d{3})+$)/g// $&指的是匹配的内容, 符合正则表达式的内容加','const strNumber = number + '';const int = Math.floor(strNumber)const floatPart = strNumber.substring(strNumber.indexOf('.')) || ''return String(int).replace(reg, '$&,') + floatPart;
}
console.log(format_width_regex('1001.02098'))
console.log(format_width_regex('938765432.02098'))function format_width_regex2(number) {// exp1(?=exp2) 查找查找exp2前面的exp1const reg = /\d{1,3}(?=(\d{3})+)/g const reg2 = /^(\d+)\.(\d+)$/;const strNumber = number + '';const int = strNumber.replace(reg2, '$1') || ''const float = reg2.test(strNumber) ? strNumber.replace(reg2, '$2') : ''return int.replace(reg, function (match, ...args) {console.log(match, ...args, '打印====')return match + ','}) + (float.padStart(float.length > 0 ? float.length + 1 : 0, '.'))
}
console.log(format_width_regex2(900))
console.log(format_width_regex2('1000'))
console.log(format_width_regex2('1001.02098'))
console.log(format_width_regex2('938765432.02098'))function format_width_regex3(number) {// 匹配的是后面是3*n个数字的非单词边界(\B)const reg = /\B(?=(?:\d{3})+(?!\d))/gconst reg2 = /^(\d+)\.(\d+)$/;const strNumber = number + '';const int = strNumber.replace(reg2, '$1') || ''const float = reg2.test(strNumber) ? strNumber.replace(reg2, '$2') : ''return int.replace(reg, function (match, ...args) {return match + ','}) + (float.padStart(float.length > 0 ? float.length + 1 : 0, '.'))
}
console.log(format_width_regex3(900))
console.log(format_width_regex3('1000'))
console.log(format_width_regex3('1001.02098'))
console.log(format_width_regex3('938765432.02098'))/**
要理解?=和?!,首先需要理解前瞻,后顾,负前瞻,负后顾四个概念:// 前瞻:
exp1(?=exp2) 查找exp2前面的exp1
// 后顾:
(?<=exp2)exp1 查找exp2后面的exp1
// 负前瞻:
exp1(?!exp2) 查找后面不是exp2的exp1
// 负后顾:
(?<!exp2)exp1 查找前面不是exp2的exp1 */
function format_with_Intl(number, minimumFractionDigits, maximumFractionDigits) {const strNumber = number + '';const float = /\./.test(strNumber) ? strNumber.split('.')[1]: '';minimumFractionDigits = minimumFractionDigits || float.length || 2maximumFractionDigits = maximumFractionDigits || float.length || 2maximumFractionDigits = Math.max(minimumFractionDigits, maximumFractionDigits)return new Intl.NumberFormat('en-us', {maximumFractionDigits,minimumFractionDigits}).format(number)
}
console.log(format_with_Intl(900))
console.log(format_with_Intl('1000'))
console.log(format_with_Intl('1001.02098'))
console.log(format_with_Intl('938765432.02098'))