【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("")
}
相关推荐
小二·15 小时前
LangGraph 多智能体实战:从零搭建 Multi-Agent 协作系统
java·开发语言·数据库
Yeats_Liao15 小时前
物联网接入层技术剖析(三):epoll在JVM中的映射
java·linux·jvm·人工智能·物联网
97zz16 小时前
Claude+deepseek-v4pro+cc switch+VSCode AI编程配置教程(Java开发专属)
java·vscode·ai编程
菜菜小狗的学习笔记16 小时前
八股(九)杂七杂八
java·后端·spring
逍遥德16 小时前
Java编程高频的“技术点”-01:自定义全局异常处理器
java·开发语言·spring boot·后端
threelab16 小时前
Three.js 3D 地图可视化 | 三维可视化 / AI 提示词
前端·javascript·人工智能·3d·着色器
爱怪笑的小杰杰16 小时前
Leaflet 高性能大数据量图圆:彻底解决缩放/拖拽偏移问题
大数据·前端·vue.js·贴图
WL_Aurora16 小时前
大数据技术之SparkCore
大数据·前端·spark·rdd
YsyaaabB16 小时前
ACM 模式通用代码模板
java·c++·python·算法