前言
封装一个函数,实现将一段阿拉伯数字转为中文读法,如:12345678 => "一千两百三十四万五千六百七十八"。需注意二和两的使用。
思路
根据中文读法,每四位都以千为最高单位读写,每四位后添加单位,所以需要对阿拉伯数字先进行四位分割,然后遍历修改为对应四位读法,然后根据分割后元素数量拼接对应单位。
实现
1. 初步实现
将num四位分割,封装_transform
用于处理分割后的每一组四位数字。
javascript
function toChineseNumber(num) {
const strs = num
.toString()
.replace(/(?=(\d{4})+$)/g, ",")
.split(",")
.filter(Boolean) // 过滤掉空字符串
const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
const units = ["", "十", "百", "千"]
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = numStr[i]
const c = chars[digit]
const u = units[numStr.length - 1 - i]
result += c + u
}
console.log(result)
}
_transform("1234")
}
toChineseNumber(1234567)
考虑0的情况
但如果传入数字包含0,则会出现问题。1204会返回"一千二百零十四",继续优化,为零则不拼接单位
。
javascript
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = numStr[i]
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if(digit === 0){
result += c
} else {
result += c + u
}
}
console.log(result)
}
还需要考虑多个连续的零
,继续优化,如果当前result末位为零则不再拼接
javascript
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
// 如果上位为零则不拼接
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
result += c + u
}
}
console.log(result)
}
遍历完成后末位不能为零
javascript
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
result += c + u
}
}
// 遍历完成后删除末位0
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
至此,_transform函数已完善。
3. 整体实现
javascript
function toChineseNumber(num) {
const strs = num
.toString()
.replace(/(?=(\d{4})+$)/g, ",")
.split(",")
.filter(Boolean) // 过滤掉空字符串
const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
const units = ["", "十", "百", "千"]
const bigUnits = ["", "万", "亿"]
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
result += c + u
}
}
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
let result = ""
for (let i = 0; i < strs.length; i++) {
const part = strs[i]
const c = _transform(part)
const u = bigUnits[strs.length - 1 - i]
result += c + u
}
console.log(result)
return result
}
至此还会有问题,当前_transform
可以正确处理0,但是如果四位分割后某一组恰好全为零,则有问题,如1200003456打印却为十二亿万三千四百五十六
,所以需要判断如果中间某一组全为零则不拼接单位。
javascript
function toChineseNumber(num) {
const strs = num
.toString()
.replace(/(?=(\d{4})+$)/g, ",")
.split(",")
.filter(Boolean) // 过滤掉空字符串
const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
const units = ["", "十", "百", "千"]
const bigUnits = ["", "万", "亿"]
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
result += c + u
}
}
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
let result = ""
for (let i = 0; i < strs.length; i++) {
const part = strs[i]
const c = _transform(part)
const u = c ? bigUnits[strs.length - 1 - i] : ""
result += c + u
}
console.log(result)
return result
}
一十
作为开头需要处理成十
javascript
function toChineseNumber(num) {
const strs = num
.toString()
.replace(/(?=(\d{4})+$)/g, ",")
.split(",")
.filter(Boolean) // 过滤掉空字符串
const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
const units = ["", "十", "百", "千"]
const bigUnits = ["", "万", "亿"]
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
const c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
result += c + u
}
}
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
let result = ""
for (let i = 0; i < strs.length; i++) {
const part = strs[i]
const c = _transform(part)
const u = c ? bigUnits[strs.length - 1 - i] : ""
result += c + u
}
// 处理 "一十" 的情况,去掉开头的 "一"
if (result.startsWith("一十")) {
result = result.replace("一十", "十")
}
console.log(result)
return result
}
toChineseNumber(1000342342)
如果需要将千位的二
变成两
javascript
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
let c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
// 处理2的情况,在千位时变为"两"
if (digit === 2 && u === "千") {
c = "两"
}
result += c + u
}
}
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
实现代码
javascript
function toChineseNumber(num) {
const strs = num
.toString()
.replace(/(?=(\d{4})+$)/g, ",")
.split(",")
.filter(Boolean) // 过滤掉空字符串
const chars = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]
const units = ["", "十", "百", "千"]
const bigUnits = ["", "万", "亿"]
function _transform(numStr) {
let result = ""
for (let i = 0; i < numStr.length; i++) {
const digit = Number(numStr[i])
let c = chars[digit]
const u = units[numStr.length - 1 - i]
if (digit === 0) {
if (result[result.length - 1] !== chars[0]) {
result += c
}
} else {
// 处理2的情况,在非个位时变为"两"
if (digit === 2 && u === "千") {
c = "两"
}
result += c + u
}
}
if (result[result.length - 1] === chars[0]) {
result = result.slice(0, -1)
}
return result
}
let result = ""
for (let i = 0; i < strs.length; i++) {
const part = strs[i]
const c = _transform(part)
const u = c ? bigUnits[strs.length - 1 - i] : ""
result += c + u
}
// 处理 "一十" 的情况,去掉开头的 "一"
if (result.startsWith("一十")) {
result = result.replace("一十", "十")
}
return result
}
拓展
如果需要匹配为壹贰叁
这种写法,只需要映射即可:
javascript
function toChineseBigNumber(num) {
const str = toChineseNumber(num)
const map = {
零: "零",
一: "壹",
二: "贰",
两: "贰",
三: "叁",
四: "肆",
五: "伍",
六: "陆",
七: "柒",
八: "捌",
九: "玖",
十: "拾",
百: "佰",
千: "仟",
万: "萬",
亿: "億",
}
return str
.split("")
.map((s) => map[s])
.join("")
}