目标
将小写的金额转化为中文大写,如99.99转为“玖拾玖圆玖角玖分”
思路
- 阿拉伯数字有对应的中文大写,需要将其转为中文大写。
- 金额分为小数部分和整数部分分别处理,整数部分和小数部分转换完成后拼接在一起即完成转换
- 小数部分比较简单,将阿拉伯数字转为中文大写后加上对应的单位即可,如0.22,2转为贰,加上单位角,然后递归处理。
- 整数部分小于4位时,单位为‘仟’,‘佰’,‘拾’,但是当位数大于四位时,在原有‘仟’,‘佰’,‘拾’的基础上需要加上单位‘万’,‘亿’,‘兆’等,因此需要将整数部分按照4个数字分为一组,每组中的数字转为大写数字加上单位,而每组中需要加上对应的单位。如12345678,先分为:‘1234’,‘5678’两组,‘1234’转为‘壹仟贰佰叁拾肆’,‘5678’转为‘伍仟陆佰柒拾捌’,然后在第一组后面加上单位‘万’。
- 整数部分转换时需要考虑有0的情况:
当有0时不用带上单位’仟‘,’佰‘等,如708转为’柒佰零捌’
多个连续的0转为大写时只有一个零,如7008转为‘柒仟零捌’。
0在一组的末尾时省略’零‘,如780转为’柒佰捌拾‘
若一组内元素全为0,则省略组单位,’万‘,’亿‘等,如700001234转为‘柒亿零壹仟贰佰叁拾肆’。
代码
function numToChar (num) {
//将数字分为两部分
let parts = num.toString().split('.')
let integer = parts[0] //整数部分
let decimal = parts[1] //小数部分
//记录单位
let decimalUnit = ['角', '分', '厘', '毫'];
let baseUnit = ['仟', '佰', '拾', ''];
let upUnit = ['万', '亿', '兆'];
//记录阿拉伯数字对应中文大写
let nums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]
//记录结果值
let res = ''
//处理小数部分
//如果不存在小数部分
if (!decimal) {
res += '整'
}else{
//去除小数部分后面的0,如900转为9
let end = decimal.length;
for(let i = decimal.length - 1; i >= 0; i--){
if (decimal[i] === '0') {
end--;
}else{
break;
}
}
decimal = decimal.substring(0, end);
//若长度大于4,则输入有误
if (decimal.length > 4) {
alert('请确认输入金额是否正确');
return
}
//若小数部分的长度为0,则输入值小数部分均为0
if (decimal.length === 0) {
res += '整'
}
//阿拉伯数字转为中文大写加上单位
Array.from(decimal).forEach((value, index) => {
if(!Number(value) === NaN) {
alert('请确认输入金额是否正确')
return
}
res += nums[value] + decimalUnit[index];
})
}
//处理整数部分
//去除整数部分前面的0,如0090转为90
let index = 0;
for (let i = 0; i < integer.length; i++) {
if(integer[i] === '0') index = i+1;
else break
}
integer = integer.substring(index);
//整数部分只有0的情况
if (!integer.length) {
res = nums[0] + '圆' + res;
}
else{
//将整数部分按照4个元素分组
//确定第一组元素的个数(第一组元素不一定是4个,如1234567分为['123', '4567'])
let stLen = integer.length % 4;
if(stLen === 0) stLen = 4;
//确定有几组
let arrLen = integer.length / 4;
//用一个数组保存分组后元素
let arrInterger = []
//记录每一组起始值的索引
let stattInd = 0;
for (let i = 0; i < arrLen; i++) {
let endIndex = i * 4 + stLen;
arrInterger[i] = integer.substring(stattInd, endIndex);
stattInd = endIndex;
}
//将整数部分转为中文大写加单位
//记录实际组数
let upLen = arrInterger.length;
//记录0出现的次数
let zero = 0;
arrInterger.forEach((value, index) => {
let temp = ''
//记录每一组内元素的个数
let len = value.length;
//遍历每一组中的元素
for (let i = 0; i < value.length; i++) {
if(value[i] === '0'){
zero ++
}else{
//若前面出现0,则加上‘零’
if (zero > 0) {
temp += nums[0]
}
//数字转为大写加上单位
temp += nums[value[i]] + baseUnit[i % 4 + 4 - len]
//0的个数归零
zero = 0;
}
}
//加上组单位
//若连续0的个数大于4,则不加组单位,若小于两组,则无组单位
if (zero < 4 && upLen -2 - index >= 0) {
temp += upUnit[upLen -2 - index];
}
//将转换后的中文大写替换原元素
arrInterger[index] = temp;
})
//整数部分分组合并,并加上小数部分
res = arrInterger.join('') + '圆' + res;
}
return res
}