小写金额转为中文大写

目标
将小写的金额转化为中文大写,如99.99转为“玖拾玖圆玖角玖分”
思路

  1. 阿拉伯数字有对应的中文大写,需要将其转为中文大写。
  2. 金额分为小数部分和整数部分分别处理,整数部分和小数部分转换完成后拼接在一起即完成转换
  3. 小数部分比较简单,将阿拉伯数字转为中文大写后加上对应的单位即可,如0.22,2转为贰,加上单位角,然后递归处理。
  4. 整数部分小于4位时,单位为‘仟’,‘佰’,‘拾’,但是当位数大于四位时,在原有‘仟’,‘佰’,‘拾’的基础上需要加上单位‘万’,‘亿’,‘兆’等,因此需要将整数部分按照4个数字分为一组,每组中的数字转为大写数字加上单位,而每组中需要加上对应的单位。如12345678,先分为:‘1234’,‘5678’两组,‘1234’转为‘壹仟贰佰叁拾肆’,‘5678’转为‘伍仟陆佰柒拾捌’,然后在第一组后面加上单位‘万’。
  5. 整数部分转换时需要考虑有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
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值