【分筋錯骨手】用最簡單的方法給數字添加千分位逗號分隔(財務千分位)

在不少商城或者統計報表的需求中,常常須要前端去把一大串傳數字每隔三位添加一個逗號,這樣的需求怎麼去高逼格實現呢? 先說爲何要加逗號,財會的同窗跟我說,他們作帳通常是按照千分位做爲標準的,每三位加個逗號是通行標準,英語中只有: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)
複製代碼

2.字符串循環

直接獲取字符串下標,不須要轉數組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.字符串不循環

爲何要用循環取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)
複製代碼

4.正則來了

爲何不用正則直接取後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)
複製代碼

5.正則升級

用了正則還寫了這麼長的代碼,實在不該該……算法

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' 留個做業,本身理解數組

6.湊整法

直接湊成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)
複製代碼

7.內置方法

說了這麼多,有沒有現成的方法可使用呢?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爲最大
}
複製代碼

7.完美方法

真的完美了嗎?讓咱們試試負數、小數、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,'.',',');
複製代碼

accounting.js

numeral

相關文章
相關標籤/搜索