数字转输出汉字的方法

1,077 阅读2分钟

需求

把输入的数字转成相应的汉字写法,输出出去。
例:1234123412340001 => 一千二百三十四万一千二百三十四亿一千二百三十四万零一

思考

  • 最基础的单位是千、百、十、个,个不需要读
  • 在朝上只用追加两个单位亿和万
  • 每八位是一个组,组内再分为四四一组如 [[1234,1234],[1234,1234]],八位是一个完整的结构,可直接拼接亿单位,四四又区分了万和万以下
  • 外层数组最后一个不用拼接亿单位
  • 外层数组的第一个可能不是两组,要判断length,加上合适的单位
  • 中间有连续0的要归并为一个
  • 末尾连续0的要舍弃
  • 不要超过Number最大值,2的53次方

实现

const ch = {
  '0': '零',
  '1': '一',
  '2': '二',
  '3': '三',
  '4': '四',
  '5': '五',
  '6': '六',
  '7': '七',
  '8': '八',
  '9': '九'
}
const unit = {
  '1': '千',
  '2': '百',
  '3': '十'
}

const NumberToChinese = num => {
  let n = Number(num)
  // 非数字或非整数不做处理
  console.log(n, '====n')
  if (Number.isNaN(n) || !Number.isInteger(n) || n > Math.pow(2, 53))
    return false

  // 划分为[[1234],[1234,1234]]的格式
  let all = [] // 外层数组
  let arrTemp = [] // 内层数组
  while (n > 0) {
    let _n = n / 10000
    console.log(_n, '===_n')
    // 如果得到整数,说明后面4位是空的,添加0000补充
    if (Number.isInteger(_n)) {
      arrTemp.unshift('0000')
    } else {
      // 取小数点后面的值,不满4位,补满
      let right = _n.toString().split('.')[1]
      right = right.length < 4 ? right.padEnd(4, '0') : right
      arrTemp.unshift(right)
    }
    // 两个一组,然后清空继续
    if (arrTemp.length === 2) {
      all.unshift(arrTemp)
      arrTemp = []
    }
    // 去除小数,再继续循环
    n = Math.trunc(n / 10000)
  }

  // 防止最后落单,有可能是内层数组length为1,也要添加
  arrTemp.length && all.unshift(arrTemp)

  // 数组第一个特殊处理,防止有效数字前面为0 的情况
  let firstArr = all[0][0]
  let i = 0
  while (i < 4) {
    if (firstArr[0] === '0') firstArr = firstArr.slice(1, firstArr.length)
    console.log(firstArr, '===firstArr')
    i++
  }
  all[0][0] = firstArr
  console.log(all, '===all')

  let len = all.length
  let _all = all.map((data, i) => {
    let unit = ''
    let dataLen = data.length
    console.log(data, '====data')
    // length为2拼接万亿数组
    if (dataLen === 2) {
      let res = data.map((n, j) => {
        if (j === 0) {
          unit = '万'
        } else {
          unit = i !== len - 1 ? '亿' : ''
        }
        console.log(unitFormat(n), unit)
        return unitFormat(n) + unit
      })
      return res.join('')
    } else {
      // length为1,拼接亿
      unit = i !== len - 1 ? '亿' : ''
      return unitFormat(data[0]) + unit
    }
  })
  return _all.join('')
}

// 拼接内层数组
const unitFormat = num => {
  if (!num) return ''
  if (num === '0000') return ''

  let arr = [...num]
  let _arr = arr.map((n, index) => {
    if (Number(n)) {
      // 单位获取
      let u = ''
      if (arr.length < 4) {
        u = unit[index + 1 + (4 - arr.length)]
      } else {
        u = unit[index + 1]
      }
      u = u || ''
      // 汉字获取
      n = ch[n]
      // 拼接返回
      return `${n}${u}`
    } else {
      // 如果是连续的0,或最后一个0,或者是最后一位,返回空
      if (arr[index + 1] === '0' || !arr[index + 1]) {
        return ''
      }
      return ch[n]
    }
  })
  arr = _arr.join('')
  return arr
}

console.log(NumberToChinese(1234123412340001))

以上就是思路实现。❤️