跳转到内容

数字转中文

刀刀

1/8/2025

0 字

0 分钟

思路

通过一个函数实现数字转中文,通过以下的思路实现:

  1. 把数字转为字符串,从后面开始4位的分割成数组,再过滤空项
  2. 循环数组,得到每项最多4个数字的数据
  3. 循环该数据得到每一个数字,设置一个映射表数组,把得到的数字转换数字类型作为索引获取相应的映射对象
  4. 设置一个单位数组映射表,通过计算索引获取对应的单位

初步实现

千位数以内

查看代码
js
function toChineseNumber(num) {
  // 数字裁剪
  const numStr = num
    .toString()
    .replace(/(?=(\d{4})+$)/g, ',')
    .split(',')
    .filter(Boolean)
  
  // 单位映射表
  const chars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
  const units = ['', '十', '百', '千']
  
  // 四个数字各自添加单位
  function _transform(n) {
    let res = ''
    for(let i = 0; i < n.length; i++) {
      const c = chars[+n[i]]
      const u = units[n.length - 1 - i]
      res += c + u
    }
  }
  
  // 裁剪后的字符串循环遍历每一项的四个数字
  for(let i = 0; i < numStr.length; i++) {
    const part = numStr[i]
    const c = _transform(part)
  }
}

console.log(toChineseNumber(5678)) // 五千六百七十八

优化

咋一看已经实现了,但是经过测试后还是有一定的小问题,比如:

  • 如果输入数字 1203,它会返回一千两百零十三,但是十位数为零一般不需要带单位,需要做判断
  • 如果输入数字 1003,它会返回一千零百零十三,连续的两个零应该只需要返回一个零,需要做判断
  • 如果输入数字 1200,经过上面的处理后它会返回一千两百零,末尾的零应该省略掉,需要做判断
  • 如果输入数字 0000,经过上面的处理后它会返回空,应该返回一个零,需要做判断
查看代码
js
function toChineseNumber(num) {
  // ...
  
  function handleZero(str) {
    return str.replace(/{2,}/g, '零').replace(/+$/g, '')
  }
  
  // 四个数字各自添加单位
  function _transform(n) {
    // 如果 0000 ,返回零
    if(n === '0000') {
      return chars[0]
    }
      
    let res = ''
    for(let i = 0; i < n.length; i++) {
      const c = chars[+n[i]]
      const u = units[n.length - 1 - i]
      // 如果是零,不设置单位
      if(c === chars[0]) {
        u = ''
      }
      res += c + u
    }
    // 去除重复零以及末尾的零
    res = handleZero(res)
    return res
  }
  
  // ...
}

完善实现

四位数以内已经实现了,现在要把万和亿的单位添加上去,完善功能,代码如下:

js
function toChineseNumber(num) {
  // ...
    
  // 裁剪后的字符串循环遍历每一项的四个数字
  const bigUnits = ['', '万', '亿']
  let result = ''
  for(let i = 0; i < numStr.length; i++) {
    const part = numStr[i]
    const c = _transform(part)
    const u = bigUnits[numStr.length - 1 - i]
    // 如果是零,不设置单位
    if(c === chars[0]) {
      u = ''
    }
    result += c + u
  }
  result = handleZero(result)
  return result
}

完整代码

完整代码
js
function toChineseNumber(num) {
  // 数字裁剪
  const numStr = num
    .toString()
    .replace(/(?=(\d{4})+$)/g, ',')
    .split(',')
    .filter(Boolean)
    
  // 单位映射表
  const chars = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
  const units = ['', '十', '百', '千']
    
  function handleZero(str) {
    return str.replace(/{2,}/g, '零').replace(/+$/g, '')
  }
    
  // 四个数字各自添加单位
  function _transform(n) {
    // 如果 0000 ,返回零
    if(n === '0000') {
      return chars[0]
    }
    
    let res = ''
    for(let i = 0; i < n.length; i++) {
      const c = chars[+n[i]]
      const u = units[n.length - 1 - i]
      // 如果是零,不设置单位
      if(c === chars[0]) {
          u = ''
      }
      res += c + u
    }
    // 去除重复零以及末尾的零
    res = handleZero(res)
    return res
  }
  
  // 裁剪后的字符串循环遍历每一项的四个数字
  const bigUnits = ['', '万', '亿']
  let result = ''
  for(let i = 0; i < numStr.length; i++) {
    const part = numStr[i]
    const c = _transform(part)
    const u = bigUnits[numStr.length - 1 - i]
    // 如果是零,不设置单位
    if(c === chars[0]) {
        u = ''
    }
    result += c + u
  }
  result = handleZero(result)
  return result
}

总体效果