前言

最近有个需求,需要把阿拉伯数字转成中文大写数字,比如:100 转换成壹佰元。话不多说,撸起袖子就是干,做野!

规则

首先我们看看百度百科大写数字,对大写规则的描述:

  1. 中文大写数字到"元"为止的,在"元"之后,应写"整"(或"正")字,在"角"之后,可以不写"整"(或"正")字。大写数字有"分"的,“分"后面不写"整”(或"正")字。

  2. 阿拉伯数字中有"0"时,举例如下:

    1. 数字中间有"0"时,中文大写要写"零"字,如 1409.50,应写成壹仟肆佰零玖元伍角

    2. 数字中间连续有几个"0"时,中文大写中间可以只写一个"零"字,如 6007.14,应写成陆仟零柒元壹角肆分

    3. 数字万位和元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写可以只写一个零字,也可以不写"零"字。如 1680.32,应写成壹仟陆佰捌拾元零叁角贰分,或者写成壹仟陆佰捌拾元叁角贰分,又如 107000.53,应写成壹拾万柒仟元零伍角叁分,或者写成壹拾万零柒仟元伍角叁分

    4. 数字角位是"0",而分位不是"0"时,中文大写"元"后面应写"零"字。如 16409.02,应写成壹万陆仟肆佰零玖元零贰分;又如 325.04,应写成叁佰贰拾伍元零肆分

思路

咋一看有点懵,这么多规则。其实稍微拆分下,问题不大。主要按以下几个步骤来实现:

  1. 数字分成整数跟小数两个部分:

    1. 整数部分,按四位分级法来处理,四位分级法就是以四位数为一个数级的分级方法,如图所示:
    2. 小数部分,就相对简单点,因为只有两位,直接匹配对应的字符串即可。
  2. 根据规则做相应的兼容,跟人生一样充满兼容。

实现

定个小目标,转换一个亿

我们需要将数字拆成整数部分与小数部分两部分,然后再把这两部分再拆成一个个数字。

function number2text(number) {const numbers = String(Number(number).toFixed(2)).split(".");const integer = numbers[0].split("");const decimal = Number(numbers[1]) === 0 ? [] : numbers[1].split("");console.log({ integer, decimal });
}number2text(100000000);

于是我们得到这样两个数组:

配置

  1. 大写数字的 0-9;

  2. 计数单位,第一位不显示,所以空出来;

  3. 级数,后面是兆、京、垓等,基本不用可以忽视;

const conf = {num: ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"],unit: ["", "拾", "佰", "仟"],level: ["", "万", "亿"]
};

四位分级

通过四位分级获取级数列表:将整数部分反转,从个位开始处理,获取计数单位并组装,然后塞进个级,如果个级塞满 4 个计数单位,则塞进万级,以此类推。

const levels = integer.reverse().reduce((pre, item, idx) => {let level = pre[0] && pre[0].length < 4 ? pre[0] : [];// 获取计数单位并组装let value =item === "0" ? conf.num[item] : conf.num[item] + conf.unit[idx % 4];level.unshift(value);if (level.length === 1) {pre.unshift(level);} else {pre[0] = level;}return pre;
}, []);

于是我们得到这样一个数组:

整数组装

遍历级数列表,同时拼接上级数名。

const _integer = levels.reduce((pre, item, idx) => {// 获取级数let _level = conf.level[levels.length - idx - 1];let _item = item.join("");return pre + _item + _level;
}, "");console.log({ _integer });

此时我们得到这样一个结果:

这显然不是我们想要的结果,多了很多,同时零万也是多余,做下兼容:

const _integer = levels.reduce((pre, item, idx) => {let _level = conf.level[levels.length - idx - 1];// 连续多个零字的部分设置为单个零字let _item = item.join("").replace(/(零)\1+/g, "$1");// 如果这一级只有一个零字,则去掉这级if (_item === "零") {_item = "";_level = "";// 否则如果末尾为零字,则去掉这个零字} else if (_item[_item.length - 1] === "零") {_item = _item.slice(0, _item.length - 1);}return pre + _item + _level;
}, "");console.log({ _integer });

此时的结果基本 OK 了:

但是根据第 1 条规则,还少了个整元。问题不大,我们处理完小数部分,再做兼容。

小数部分

小数部分简单遍历即可。

let _decimal = decimal.map((item, idx) => {const unit = ["分", "角"];const _unit = item !== "0" ? unit[unit.length - idx - 1] : "";return `${conf.num[item]}${_unit}`;}).join("");

输出

最后把之前漏掉的整元字补上,到此小目标一个亿实现了。

// 如果是整数,则补个整字
return `${_integer}元` + (_decimal || "整");

测试

代码写完只能说完成一半,只有测试通过才能说,这个功能实现了,我们按照规则的示例测试下:

number2text(100000000); //壹亿元整
number2text(1409.5); //壹仟肆佰零玖元伍角零
number2text(6007.14); //陆仟零柒元壹角肆分
number2text(1680.32); //壹仟陆佰捌拾元叁角贰分
number2text(107000.53); //壹拾万柒仟元伍角叁分
number2text(16409.02); //壹万陆仟肆佰零玖元零贰分
number2text(325.04); //叁佰贰拾伍元零肆分

1680.32 可以写成壹仟陆佰捌拾元零叁角贰分,或者写成壹仟陆佰捌拾元叁角贰分,测试通过,收工!

完整代码

/*** @description 数字转中文数码** @param {Number|String}   num     数字[正整数]* @param {String}          type    文本类型,lower|upper,默认upper** @example number2text(100000000) => "壹亿元整"*/
export const number2text = (number, type = "upper") => {// 配置const confs = {lower: {num: ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"],unit: ["", "十", "百", "千", "万"],level: ["", "万", "亿"]},upper: {num: ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"],unit: ["", "拾", "佰", "仟"],level: ["", "万", "亿"]},decimal: {unit: ["分", "角"]},maxNumber: 999999999999.99};// 过滤不合法参数if (Number(number) > confs.maxNumber) {console.error(`The maxNumber is ${confs.maxNumber}. ${number} is bigger than it!`);return false;}const conf = confs[type];const numbers = String(Number(number).toFixed(2)).split(".");const integer = numbers[0].split("");const decimal = Number(numbers[1]) === 0 ? [] : numbers[1].split("");// 四位分级const levels = integer.reverse().reduce((pre, item, idx) => {let level = pre[0] && pre[0].length < 4 ? pre[0] : [];let value =item === "0" ? conf.num[item] : conf.num[item] + conf.unit[idx % 4];level.unshift(value);if (level.length === 1) {pre.unshift(level);} else {pre[0] = level;}return pre;}, []);// 整数部分const _integer = levels.reduce((pre, item, idx) => {let _level = conf.level[levels.length - idx - 1];let _item = item.join("").replace(/(零)\1+/g, "$1"); // 连续多个零字的部分设置为单个零字// 如果这一级只有一个零字,则去掉这级if (_item === "零") {_item = "";_level = "";// 否则如果末尾为零字,则去掉这个零字} else if (_item[_item.length - 1] === "零") {_item = _item.slice(0, _item.length - 1);}return pre + _item + _level;}, "");// 小数部分let _decimal = decimal.map((item, idx) => {const unit = confs.decimal.unit;const _unit = item !== "0" ? unit[unit.length - idx - 1] : "";return `${conf.num[item]}${_unit}`;}).join("");// 如果是整数,则补个整字return `${_integer}元` + (_decimal || "整");
};

js如何实现阿拉伯数字转中文大写数字相关推荐

  1. 将阿拉伯数字转换为中文大写数字 —— pyhton实现

    将阿拉伯数字转换为中文大写数字 -- pyhton实现 在银行的日常业务中,常常需要用到将阿拉伯数字转换为中文大写数字的 功能.这次实验将编写一个程序,将用户输入的阿拉伯数字代表的金额,转换为大写数字 ...

  2. Python:阿拉伯数字转换为中文大写数字(金额的读数规则)

    萌萌帮班里同学做了一个python的编程作业,正好回顾一下python基础知识,以下源码和思考过程,代码全部原创. IDE:pycharm python版本:python3.7 ''' 实验目的:在银 ...

  3. 阿拉伯数字转换为中文大写数字

    这个功能使用场景不多,百度也能找到很多相关代码,只不过我找了几个看的不是很明白,为了锻炼自己的思维能力,所以就干脆自己写了一个,不仅分享代码,同时也分享一下我的思路 JS代码 let moneyCas ...

  4. Lua阿拉伯数字转中文大写数字

    function numberToString(szNum)---阿拉伯数字转中文大写local szChMoney = ""local iLen = 0local iNum = ...

  5. Python 阿拉伯数字转换为中文大写数字

    题目 python练习的一个小实验,  题目如下图: 附阿拉伯数字对应的中文大写: 思路 1. 通过定义一个字典进行阿拉伯数字与大写中文的对比储存 2. 将用户的输入首先分割为整数与小数部分分别进行处 ...

  6. 阿拉伯数字和中文大写形式的相互转换

    将阿拉伯数字转化为中文大写是很简单很实用的功能,但由于0这个特殊数字的存在使得实现起来并非那么容易,实现这一功能的关键就是对0的正确处理.该程序是我几个月之前写成的,当时没有加注释,现在程序的实现细节 ...

  7. 阿拉伯数字转中文大写和中文小写封装工具类

    package com.springboot.entity.utils; import lombok.extern.slf4j.Slf4j; /**  * @author maniac  * date ...

  8. 把阿拉伯数字翻译成中文大写数字

    package com.zcw.zcwbook.demo15;/*** @program: zcwbook* @description: 把阿拉伯数字翻译成中文大写数字* @author: zhaoc ...

  9. 【工具封装】Python 实现将阿拉伯数字 === 转换成中文大写数字

    一.序言:   工具封装第四弹,阿拉伯数字 ===> 转换成 ===> 中文大写数字,喜欢就赶紧收藏+点赞+关注吧 !!! ---- Nick.Peng 二.实现代码如下: #!/usr/ ...

最新文章

  1. 通过yiic来创建yii应用
  2. php第三方登录代码,thinkPHP5项目中实现QQ第三方登录功能
  3. spring.profiles.active配置了没生效_微服务架构之「 配置中心 」
  4. Redis 究竟适不适合当队列来用?
  5. Markdown入门教程
  6. LeetCode--27. 移除元素(双指针)
  7. 广东发布全国首批“网络视听产业试点机构”名单 虎牙获001号授牌
  8. java面向对象内存分析
  9. junit return null该怎么测试_3 分钟生成一个单元测试报告,这个样式爱了
  10. 现实竞争激烈,学透才能在职场做个风云人物,单片机存储器篇
  11. 网络抓包工具--wireshark
  12. 中望cad文字显示问号怎么办_中望CAD图纸显示乱码怎么办?
  13. 如何在 HTML 中将表格居中
  14. NSIS静默安装VC运行库插件
  15. 业务流程与组织结构优化
  16. 关于ADC芯片的选型
  17. ubuntu server 14.04 编译安装xen4.4.2配置vtpm(二)——Dom0内核编译
  18. 【hdu 5512】【 2015ACM/ICPC亚洲区沈阳站】Pagodas 题意&题解&代码(C++)
  19. 非梯度类启发式搜索算法:Nelder Mead
  20. 2020年华东师大研究生机试题

热门文章

  1. 【SealDEV 倾情奉献】Android APK 安装过程详解
  2. python map函数的作用_Python map()函数介绍及用法
  3. 攻城略地mysql充值_攻城掠地充值有巨惠!平台折扣5.0超划算
  4. 台式计算机操作系统的安装方法,台式机电脑重装win10系统详细教程
  5. 《工业控制网络安全技术与实践》一第1章 绪  论
  6. 百度云主机wordpress设置伪静态方法
  7. 大数据专业就业岗位有哪些?
  8. 建网站,买域名和虚拟空间总共要多少钱?
  9. Pandas 中 SettingwithCopyWarning 的原理和解决方案
  10. p2p 企业信贷 UML 跨行清算