因爲公司業務週期較短,時常是幾個項目一塊兒作,或是加上bug修復。上午的時候接到個任務,正式上的網站發現以下圖的錯誤。 前端
找到項目中對應頁面,很快發現了問題,原來以前的哥們經過定義了個數組,經過序號來取對應的中文。這樣的方式缺點很明顯,個數有限。致使如今出現不夠用的情況。 正則表達式
通過考慮以爲能夠抽出一個公共的方法代碼以下:數組
/**
* 根據輸入的數字返回對應是中文,格式如:三十一
* @param {Number} index 序號
*/
export function covertNumberTochinese(index) {
const multiple = parseInt((index + 1) / 10)
const remainder = (index + 1) % 10
const weekheadNum = [
'一',
'二',
'三',
'四',
'五',
'六',
'七',
'八',
'九',
'十'
]
let text = ''
const textMap = new Map([
[/^1_[0-9]$/, () => `十${weekheadNum[remainder - 1]}`],
[/^1_0$/, () => `十`],
[
/^[2-9]_[1-9]$/,
() => `${weekheadNum[multiple - 1]}十${weekheadNum[remainder - 1]}`
],
[/^[2-9]_0$/, () => `${weekheadNum[multiple - 1]}十`],
[/^0_\w/, () => `${weekheadNum[remainder - 1]}`]
])
const textList = [...textMap].filter(([reg]) => {
return reg.test(multiple + '_' + remainder)
})
textList.forEach(([reg, callBack]) => {
text = callBack()
})
return text
}
複製代碼
用上面的方法能夠將數字匹配到中午 1-99位,雖然項目中是夠用了,可是侷限性仍是很大,並且判斷的條件不少,邏輯不直觀。瀏覽器
/**
* 根據輸入的數字返回對應是中文,格式如:一千零一
* @param {Number|String} index 序號或者數字開頭的字符串
*/
export numberToChinese(number) {
number = String(parseInt(number))
const ChineseText = '零一二三四五六七八九'
const smallUnit = '十百千'
const length = number.length
let n = length - 2
let string = ''
for (var i = 0; i < length; i++) {
let num = number.charAt(i)
string += ChineseText.charAt(num)
string += num > 0 ? smallUnit.charAt(n) : ''
n--
}
return string
}
複製代碼
.charAt
方法取對應位數的中文。四位數如下
的轉換,位數增長方法是相似的)拼接
的方式獲得一箇中文的數字,這裏n表明取第幾位單位也就是取smallUnit
的第幾位ChineseText
中的中文獲得中文的一從十開始
的而不是從個位數開始,而且.charAt(0)取的是字符串的第一位
。而且當數字爲零的時候不須要單位,因此加了num > 0的限定條件。就此數字轉換成中文的方法就寫完了,在瀏覽器中打印以下 bash
有多個零的時候咱們習慣是一千零一,而且結尾爲零的時候是省略的 因此 咱們還得對返回的string作一下去零處理/**
* 根據輸入的字符串返回按照規則去零後的字符串,格式如:一千零一
* @param {string} str 中文數字 如 一千零零一
*/
export clearZero(str){
const regMiddle = /零{2}/g
const regEnd = /零?零$/
str = str.replace(regMiddle, '零')
return str.replace(regEnd, '')
}
複製代碼
將 numberToChinese 函數改成以下數據結構
export numberToChinese(number) {
number = String(parseInt(number))
const ChineseText = '零一二三四五六七八九'
const smallUnit = '十百千'
const length = number.length
let n = length - 2
let string = ''
for (var i = 0; i < length; i++) {
let num = number.charAt(i)
string += ChineseText.charAt(num)
string += num > 0 ? smallUnit.charAt(n) : ''
n--
}
return clearZero(string)
}
複製代碼
charAt
取數字字符串,而後經過數組去找定義好的ChineseText對應的中文,定義了一個n
來取當前位數對應的單位首先感謝你們在留言區發表本身寶貴的意見,能拋磚引玉讓你們分享本身工做經驗 如下代碼截取 @皈依佛門小前端在留言區的評論函數
function chin(str){
let cnChar = "零壹貳叄肆伍陸柒捌玖",
partInt = '元拾佰仟萬拾佰仟億拾佰仟',
len = str.length-1,
arr = new Array((len+1)),
i=0;
str.replace(/\d/g, n => {
let b = partInt.charAt(len-i);
arr[i] = cnChar.charAt(n) + (n==='0' && '元萬億'.indexOf(b) < 0 ? '' : b);
i++;
});
return arr.join('').replace(/(零)\1+/g,'零').replace(/零(十|百|千|萬|億|元)/g, value => value.replace(/零/, ''));
}
複製代碼
接下來分析下以上代碼網站
數值以及單位
做爲一項,最後經過
數組join
的方法所有拼接在一塊兒。而後進行
去零處理
。
let b = partInt.charAt(len-i);
arr[i] = cnChar.charAt(n) + (n==='0' && '元萬億'.indexOf(b) < 0 ? '' : b)
複製代碼
效果以下: ui
/**
* 根據輸入的數字返回對應是中文,格式如:一千零一
* @param {Number|String} index 序號或者數字開頭的字符串
*/
export numberToChinese(number) {
number = String(parseInt(number))
const ChineseText = '零一二三四五六七八九'
const unit = '十百千萬十百千億十百千'
const length = number.length
let n = length - 2
let string = ''
for (var i = 0; i < length; i++) {
let num = number.charAt(i)
let currentUnit = unit.charAt(n)
string += ChineseText.charAt(num)
// 經過下面這步至關於將字符串分割成四位一組,由於每四位都會有一個單位,因此零不可能相連超過兩個了。
string +=
num === '0' && '萬億'.indexOf(currentUnit) < 0 ? '' : currentUnit
n--
}
return this.clearZero(string)
}
複製代碼
/**
* 根據輸入的字符串返回按照規則去零後的字符串,格式如:一千零一
* @param {string} str 中文數字 如 一千零零一
*/
export clearZero(str){
const regMiddle = /零{2}/g
const regEnd = /零?零$/
const regTen = /一十/g
str = str.replace(regMiddle, '零')
str = str.replace(regTen, '十')
return str.replace(regEnd, '')
}
複製代碼