【JS】数字转中文读写方式

前言

封装一个函数,实现将一段阿拉伯数字转为中文读法,如: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("")
}
相关推荐
逊嘘4 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
morris13111 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
别拿曾经看以后~13 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死16 分钟前
导航栏及下拉菜单的实现
前端·css·css3
川石课堂软件测试19 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
科技探秘人28 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人28 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR34 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香36 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员36 分钟前
java导出word文件(手绘)
java·开发语言·word