js如何实现阿拉伯数字转中文大写数字
前言
最近有个需求,需要把阿拉伯数字转成中文大写数字,比如:100 转换成壹佰元。话不多说,撸起袖子就是干,做野!
规则
首先我们看看百度百科大写数字
,对大写规则的描述:
中文大写数字到"元"为止的,在"元"之后,应写"整"(或"正")字,在"角"之后,可以不写"整"(或"正")字。大写数字有"分"的,“分"后面不写"整”(或"正")字。
阿拉伯数字中有"0"时,举例如下:
数字中间有"0"时,中文大写要写"零"字,如
1409.50
,应写成壹仟肆佰零玖元伍角
。数字中间连续有几个"0"时,中文大写中间可以只写一个"零"字,如
6007.14
,应写成陆仟零柒元壹角肆分
。数字万位和元位是"0",或者数字中间连续有几个"0",万位、元位也是"0",但千位、角位不是"0"时,中文大写可以只写一个零字,也可以不写"零"字。如
1680.32
,应写成壹仟陆佰捌拾元零叁角贰分
,或者写成壹仟陆佰捌拾元叁角贰分
,又如107000.53
,应写成壹拾万柒仟元零伍角叁分
,或者写成壹拾万零柒仟元伍角叁分
。数字角位是"0",而分位不是"0"时,中文大写"元"后面应写"零"字。如
16409.02
,应写成壹万陆仟肆佰零玖元零贰分
;又如325.04
,应写成叁佰贰拾伍元零肆分
。
思路
咋一看有点懵,这么多规则。其实稍微拆分下,问题不大。主要按以下几个步骤来实现:
数字分成整数跟小数两个部分:
- 整数部分,按四位分级法来处理,四位分级法就是以四位数为一个数级的分级方法,如图所示:
- 小数部分,就相对简单点,因为只有两位,直接匹配对应的字符串即可。
- 整数部分,按四位分级法来处理,四位分级法就是以四位数为一个数级的分级方法,如图所示:
根据规则做相应的兼容,跟人生一样充满兼容。
实现
定个小目标,转换一个亿
我们需要将数字拆成整数部分与小数部分两部分,然后再把这两部分再拆成一个个数字。
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);
于是我们得到这样两个数组:
配置
大写数字的 0-9;
计数单位,第一位不显示,所以空出来;
级数,后面是兆、京、垓等,基本不用可以忽视;
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如何实现阿拉伯数字转中文大写数字相关推荐
- 将阿拉伯数字转换为中文大写数字 —— pyhton实现
将阿拉伯数字转换为中文大写数字 -- pyhton实现 在银行的日常业务中,常常需要用到将阿拉伯数字转换为中文大写数字的 功能.这次实验将编写一个程序,将用户输入的阿拉伯数字代表的金额,转换为大写数字 ...
- Python:阿拉伯数字转换为中文大写数字(金额的读数规则)
萌萌帮班里同学做了一个python的编程作业,正好回顾一下python基础知识,以下源码和思考过程,代码全部原创. IDE:pycharm python版本:python3.7 ''' 实验目的:在银 ...
- 阿拉伯数字转换为中文大写数字
这个功能使用场景不多,百度也能找到很多相关代码,只不过我找了几个看的不是很明白,为了锻炼自己的思维能力,所以就干脆自己写了一个,不仅分享代码,同时也分享一下我的思路 JS代码 let moneyCas ...
- Lua阿拉伯数字转中文大写数字
function numberToString(szNum)---阿拉伯数字转中文大写local szChMoney = ""local iLen = 0local iNum = ...
- Python 阿拉伯数字转换为中文大写数字
题目 python练习的一个小实验, 题目如下图: 附阿拉伯数字对应的中文大写: 思路 1. 通过定义一个字典进行阿拉伯数字与大写中文的对比储存 2. 将用户的输入首先分割为整数与小数部分分别进行处 ...
- 阿拉伯数字和中文大写形式的相互转换
将阿拉伯数字转化为中文大写是很简单很实用的功能,但由于0这个特殊数字的存在使得实现起来并非那么容易,实现这一功能的关键就是对0的正确处理.该程序是我几个月之前写成的,当时没有加注释,现在程序的实现细节 ...
- 阿拉伯数字转中文大写和中文小写封装工具类
package com.springboot.entity.utils; import lombok.extern.slf4j.Slf4j; /** * @author maniac * date ...
- 把阿拉伯数字翻译成中文大写数字
package com.zcw.zcwbook.demo15;/*** @program: zcwbook* @description: 把阿拉伯数字翻译成中文大写数字* @author: zhaoc ...
- 【工具封装】Python 实现将阿拉伯数字 === 转换成中文大写数字
一.序言: 工具封装第四弹,阿拉伯数字 ===> 转换成 ===> 中文大写数字,喜欢就赶紧收藏+点赞+关注吧 !!! ---- Nick.Peng 二.实现代码如下: #!/usr/ ...
最新文章
- 通过yiic来创建yii应用
- php第三方登录代码,thinkPHP5项目中实现QQ第三方登录功能
- spring.profiles.active配置了没生效_微服务架构之「 配置中心 」
- Redis 究竟适不适合当队列来用?
- Markdown入门教程
- LeetCode--27. 移除元素(双指针)
- 广东发布全国首批“网络视听产业试点机构”名单 虎牙获001号授牌
- java面向对象内存分析
- junit return null该怎么测试_3 分钟生成一个单元测试报告,这个样式爱了
- 现实竞争激烈,学透才能在职场做个风云人物,单片机存储器篇
- 网络抓包工具--wireshark
- 中望cad文字显示问号怎么办_中望CAD图纸显示乱码怎么办?
- 如何在 HTML 中将表格居中
- NSIS静默安装VC运行库插件
- 业务流程与组织结构优化
- 关于ADC芯片的选型
- ubuntu server 14.04 编译安装xen4.4.2配置vtpm(二)——Dom0内核编译
- 【hdu 5512】【 2015ACM/ICPC亚洲区沈阳站】Pagodas 题意&题解&代码(C++)
- 非梯度类启发式搜索算法:Nelder Mead
- 2020年华东师大研究生机试题
热门文章
- 【SealDEV 倾情奉献】Android APK 安装过程详解
- python map函数的作用_Python map()函数介绍及用法
- 攻城略地mysql充值_攻城掠地充值有巨惠!平台折扣5.0超划算
- 台式计算机操作系统的安装方法,台式机电脑重装win10系统详细教程
- 《工业控制网络安全技术与实践》一第1章 绪 论
- 百度云主机wordpress设置伪静态方法
- 大数据专业就业岗位有哪些?
- 建网站,买域名和虚拟空间总共要多少钱?
- Pandas 中 SettingwithCopyWarning 的原理和解决方案
- p2p 企业信贷 UML 跨行清算