前端在业务开发中经常会遇到将数字转换为中文的需求,例如:
- 有序列表循环使用一、二、三代替1、2、3
- 人民币数字转中文大写圆角分
第一种情况当条目少的时候可以写死,但是当条目不固定且条目多的时候,就需要有通用的转换方法,第二种情况更不用多说了,下面是我自己实现转换方法的代码示例,以转人民币大写为例。
思路如下:
- 中文位数:个、十、百、千、万、十万、百万、千万、亿、十亿、百亿、千亿、万亿、十万亿......
- 通过上面的规律,按照每四位拆分,【个、十、百、千】(个),【个、十、百、千】(万),【个、十、百、千】(亿),【个、十、百、千】(万亿)
- 每四位拆分后的大节点是【个、万、亿、万亿】,则大节点前面的小节点统一为【个、十、百、千】
- 每一位数字都有0-9十个数
const moneyToCN = (money) => {
if (Number(money) !== Number(money)) {
return money
}
const cnFigure = ['', '万', '亿', '万亿']
const cnInteger = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
const cnDecimalism = ['', '拾', '佰', '仟']
const string = money + ''
const numbers = string.split('.')
const integerPart = numbers[0]
const decimalPart = numbers[1]
const len = integerPart.length
const pitch = Math.ceil(len / 4)
const array = []
for (let index = 0; index < pitch; index++) {
array.push(integerPart.slice((len - (index + 1) * 4 < 0) ? 0 : (len - (index + 1) * 4), len - index * 4))
}
const cnArray = array.map((figure, index) => {
const cn = figure.split('').map((char, i) => {
return char === '0' ? '零' : (cnInteger[Number(char)] + cnDecimalism[figure.length - i - 1])
}).join('').replace(/\u96f6+$/, '').replace(/\u96f6+/g, '\u96f6')
return cn.length ? (cn + cnFigure[index]) : (cnFigure[index] ? '零' : '')
}).reverse()
const integerCN = cnArray.join('').replace(/\u96f6+/g, '\u96f6')
let decimalCN = ''
if (!decimalPart || decimalPart === '0' || decimalPart === '00') {
decimalCN = '整'
} else {
const [p0, p1] = decimalPart.split('')
decimalCN = (p0 === '0' ? '零' : (cnInteger[Number(p0)] + '角')) + (!p1 || p1 === '0' ? '' : (cnInteger[Number(p1)] + '分'))
}
return `${integerCN || '零'}圆${decimalCN}`
}
复制代码