在不少商城或者統計報表的需求中,常常須要前端去把一大串傳數字每隔三位添加一個逗號,這樣的需求怎麼去高逼格實現呢? 先說爲何要加逗號,財會的同窗跟我說,他們作帳通常是按照千分位做爲標準的,每三位加個逗號是通行標準,英語中只有:B=billion,第二逗號 M=million,第三逗號 T=thousand BMT(別摸它)javascript
如今開始寫代碼o(╯□╰)o前端
將數字轉換成字符串,再分隔成字符串數組,每3位前面加逗號,再拼成字符串。 閉着眼睛都知道這麼麻煩的方法必定不是個人逼格java
function thousands(num) {
var result = [], counter = 0;
num = (num || 0).toString().split('');
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result.unshift(num[i]);
if (!(counter % 3) && i != 0) { result.unshift(','); }
}
console.log(result.join(''));
}
thousands(314159265354)
複製代碼
直接獲取字符串下標,不須要轉數組git
function thousands(num) {
var result = '', counter = 0;
num = (num || 0).toString();
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result = num.charAt(i) + result;
if (!(counter % 3) && i != 0) { result = ',' + result; }
}
console.log(result);
}
thousands(314159265354)
複製代碼
爲何要用循環取3位,直接截取很差嗎?github
function thousands(num) {
var num = (num || 0).toString(), result = '';
while (num.length > 3) {
result = ',' + num.slice(-3) + result;
num = num.slice(0, num.length - 3);
}
if (num) { result = num + result; }
console.log(result);
}
thousands(314159265354)
複製代碼
爲何不用正則直接取後3位?正則表達式
function thousands(num) {
var num = (num || 0).toString(), reg = '/\d{3}$/', result = ''; //匹配三個數字字符
while (reg.test(num) ) {
result = RegExp.lastMatch + result;//返回上一次正則表達式搜索過程當中最後一個匹配的文本字符串。
if (num !== RegExp.lastMatch) {
result = ',' + result;
num = RegExp.leftContext;//返回上一次正則表達式匹配時,被搜索字符串中最後一個匹配文本以前(不包括最後一個匹配)的全部字符。
} else {
num = '';
break;
}
}
if (num) { result = num + result; }
console.log(result);
};
thousands(314159265354)
複製代碼
用了正則還寫了這麼長的代碼,實在不該該……算法
function thousands(num) {
// \B 匹配非單詞邊界,匹配位置的左右兩邊都是 \w([a-zA-Z0-9_])
// ?=是先行斷言,表示這個位置後面的內容須要知足的條件,注意只是匹配一個位置,並不匹配具體的字符,因此是零寬;
// ?!後行斷言,表示這個位置後面的內容不能知足的條件,(?!\d)表示接下來的位置不是數字,能夠是小數點
// \d{3}匹配三個數字,+表示前面的內容重複1到屢次,也就是匹配3個數字一到屢次,3的倍數字符串
// (?=(\d{3})+(?!\d))匹配一個位置,這個位置後面首先是3的倍數個數字的字符串,接下來的位置不是數字
console.log(num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
}
thousands(314159265354.99)
複製代碼
其實正則還可更短點的 '/\B(?=(\d{3})+\b)/g' 留個做業,本身理解數組
直接湊成3的部分不就簡單多了嗎?ide
function thousands(num) {
var num = (num || 0).toString(), temp = num.length % 3;
switch (temp) {
case 1:
num = '00' + num;
break;
case 2:
num = '0' + num;
break;
}
console.log (num.match(/\d{3}/g).join(',').replace(/^0+/, ''));
}
thousands(314159265354)
複製代碼
說了這麼多,有沒有現成的方法可使用呢?ui
var number = 314159265354;
//千分位分隔
console.log(number.toLocaleString('en-US'));//314,159,265,354
// nu 擴展字段要求編號系統,e.g. 中文十進制
console.log(number.toLocaleString('zh-Hans-CN-u-nu-hanidec'));// 三一四,一五九,二六五,三五四
//貨幣格式歐元
console.log(number.toLocaleString('ja-JP', { style: 'currency', currency: 'EUR',currencyDisplay:'name'}))
numObj.toLocaleString([locales [, options]])
locales:'',//可選語言 格式 language[-scripts][-region]-u-nu-*
options:{
localeMatcher:'',//匹配算法
style:'',//「decimal」表示純數字格式 , 「currency」表示貨幣格式, 和"percent"表示百分比格式
currency:'',//貨幣代碼
currencyDisplay:'',//如何在貨幣格式化中顯示貨幣,標誌或者名稱
useGrouping:'',//是否使用分隔符
minimumIntegerDigits:'',//使用的整數數字的最小位數.可能的值是從1到21
minimumFractionDigits:'',//使用的小數數字的最小位數.可能的值是從0到20 maximumFractionDigits爲最大
minimumSignificantDigits:''//使用的有效數字的最小位數。可能的值是從1到21 maximumSignificantDigits爲最大
}
複製代碼
真的完美了嗎?讓咱們試試負數、小數、0、undefined吧
function number_format(strInput, decimals, dec_point, thousands_sep) {
var number = strInput;
if (typeof(number) === 'string') {
//字符串轉數字
number = parseFloat(number.replace(/[^\-\d\.]/g, ''));
}
var n = !isFinite(+number) ? 0 : +number, //檢查整數有限值,隱式轉數字類型
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),//檢查保留小數位數有限值,並取絕對值
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,//設置千分位標誌
dec = (typeof dec_point === 'undefined') ? '.' : dec_point;//設置小數標誌
if (!Number.prototype._toFixed) {
Number.prototype._toFixed = Number.prototype.toFixed;
}
Number.prototype.toFixed = function(prec) {
return (this + 3e-16)._toFixed(prec);
};
s = (prec ? toFixedFix(n, prec) : Math.round(n)).toString().split('.');//切割整數和小數
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);//千分位分隔
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');//補充小數
}
return s.join(dec);
}
function test(number, decimals, dec_point, thousands_sep) {
console.log(number_format(number, decimals, dec_point, thousands_sep));
}
test('-1111111.222222',3,'.',',');
複製代碼