01-数字格式化toLocaleString() 100,000,000

题目

每三个0之间加一个逗号,期望效果 100,000,000

let str = '100000000'

实现

1、简单版

num.toLocaleString()方法

let str = '100000000'
console.log(Number(str).toLocaleString());
// 100,000,000

2、面试版

核心:replace+正则

实现思路:用正则写一个前瞻,判断每三个数字加一个逗号,去除边界

tips:

  • 前瞻就是一种条件判断,好比if语句
  • (?=exp)正向前瞻 匹配后面满足表达式exp的位置
  • (?!exp) 负向前瞻 匹配后面不满足表达式exp的位置
  •  \d :表示任意的一位数字,等价于“[0-9]”;
  • /g 全局,表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
  • replace(替换目标,替换成什么)
  • \d{3}$ 数字出现3次结束判断
  • (\d{3})+$)  每三个数字替换一次
  • \B 单词边界不替换
let str1 = str.replace(/(?=\B(\d{3})+$)/g, ',')
console.log(str1)  // 100,000,000

以上不能处理小数点的情况,下面来实现一下小数点的。


进阶:格式化金额数字

1、简单版

tips:

style 表示格式化时使用的样式,默认值是 decimal 也就是纯数字,也可为 percent 百分比显示与 currency 货币显示。值为 currency 时必须同时指定 options 中的 currency 属性,否则报错。

“USD” 表示美元, “EUR” 表示欧元, "CNY"是人民币

  • toLocaleString()
function moneyFormats(value) {
let a = Number(value) //转为数字格式
let b = a.toLocaleString('zh', { style: 'currency', currency: 'CNY' })
// let b = a.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
// let b = a.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
return b
}

let num1 = '3598498468.088685'
let num2 = moneyFormats(num1)
console.log(num2) // ¥3,598,498,468.09
  • new Intl.NumberFormat()+format
function moneyFormats1(value) {
let a = Number(value) //转为数字格式
let b =  new Intl.NumberFormat('zh', { style: 'currency', currency: 'CNY' }).format(Number(value))
// let b = a.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
// let b = a.toLocaleString('de-DE', { style: 'currency', currency: 'EUR' })
return b
}

let num1 = '3598498468.088685'
let num3 = moneyFormats1(num1)
console.log(num3)  // ¥3,598,498,468.09

2、通用版

按照业务需求,格式化金额数字。
要求:1、每隔三位数字用逗号分隔。2、只保留两位小数。3、小数四舍五入。

    isFinite(): 函数可确定数字是否是有限的合法数字

    num:格式化目标数字

    decimal:保留几位小数,默认2位

    split:千分位分隔符,默认为,

    Math.pow(底数x,指数y)

    Math.round() 精准的四舍五入成整数

    toFixed(要保留位数) 并非四舍五入,而是四舍六入,是银行家的舍入规则。

    moneyFormat(123456789.878, 2, ',') // 123,456,789.88

思路:

  • 如果是0,则直接toFixed(2)添加两位小数
  • 如果非0,则indexOf()查找是否有小数点,返回-1则是整数,返回所在位置则是非整数
  • 如果是整数,整数部分用正则变成逢三一断,拼接上小数点和0就行
  • 如果是非整数,利用Math.round()四舍五入,再利用toFixed()保留两位小数,直接用toFixed()会有失精度,再将num转换成字符串,从小数点所在位置开始截取两位小数,最后再拼接正则转换好的整数部分和小数部分即可
function moneyFormat (num, decimal = 2, split = ',') {
  if (isFinite(num)) { // num是数字
    if (num === 0) { // 为0
      return num.toFixed(decimal)
    } else { // 非0
      let res = ''
      let dotIndex = String(num).indexOf('.')
      if (dotIndex === -1) { // 整数
        res = String(num).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`) + '.' + '0'.repeat(decimal)
      } else { // 非整数
        const numStr = String((Math.round(num * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal)) // 四舍五入,然后固定保留2位小数
        const decimals = numStr.slice(dotIndex, dotIndex + decimal + 1) // 截取小数位
        res = String(numStr.slice(0, dotIndex)).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`) + decimals
      }
      return res
    }
  } else {
    return '--'
  }
}
console.log(moneyFormat(1234789.876)) 
console.log(moneyFormat(0)) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值