digitToChinese方法--将任意数字转化转化为汉语习惯的中文

385 阅读1分钟

背景

在一次项目的重构中,遇到了需要将服务端返回的阿拉伯数字转为汉语习惯的中文展示到页面中的需求。原来服务端返回的数字范围在1-21之间,之前的代码开发者可能开发比较急,用switch/case一一对应的方法写,代码显得很冗长。当然也可以直接用两个数组,元素分别为数字和对应的汉语来匹配。但并不具有普遍性,如果我的数字范围很大,是不是这两个数组长度就要很长。所以就想实现一个可以支持将任意数字转化转化为汉语习惯的中文的方法(比如11转化为十一,10111转化为一万零一百一十一)

实现

function digitToChinese(num) {
    //  0-9数字对应的汉字
    const digitMap = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
    // 数字对应的后缀单位
    const perUnit = ['千', '百', '十', ''];
    // 每四位数字一组的后缀单位
    const unit = ['亿', '万', ''];
    // 将数字拆分,每四位一组,作为数组的一个元素 比如123389==>['12','3389']
    const formateArr = num
      .toString()
      .replace(/\B(?=(\d{4})+$)/g, ',')
      .split(',');
    // 计算四位一组要加的后缀单位的起始偏移量,比如123389,那每四位一组的后缀单位应该从unit的第1个元素(万)开始匹配
    const unitOffset = unit.length - formateArr.length;
    // reduce每次遍历返回本次拼凑上一组转化好的中文,最后处理一下数字十几的情况,把前面的'一'去掉,比如11,'一十一'变成'十一'
    return formateArr.reduce((result, next, unitIdx) => {
    // 处理本组数字,计算数字后缀单位的起始偏移量,比如123389,第一组123,那数字的后缀单位应该从perUnit的第1个元素开始匹配
      const perOffset = perUnit.length - next.length;
      const tempStr =
        [...next]
          .reduce(
            (preRes, num, idx) =>
              preRes + digitMap[num] + perUnit[idx + perOffset],
            ''
          )
          // 处理中间出现多个零只显示一个零
          .replace(/零[千|百|十]*/g, '零')
          // 处理结尾为零的情况
          .replace(/零+$/, '') + unit[unitIdx + unitOffset];
      return result + tempStr;
    }, '').replace(/^一(?=十)/, '');
  }

实例实践

copy.png