자바스크립트를 억이나 만으로 바꾸고 싶을 때 넘버포마의 notation:compact가 편해요.

18768 단어 JavaScriptintltech
우연한 계기로 notation:“compact”라는 옵션을 찾았는데 편리했어요.
const fmt =  new Intl.NumberFormat("ja-JP",{ 
    notation: "compact",
})

fmt.format(BigInt(64 ** 8) )
// => "281兆"
어쨌든 대체적으로 수치를 낼 때는 매우 편리하다.최고인 것 같아.

조합 옵션


자세한 내용은 위의 MDN이 비교적 상세하지만 다른 옵션과 조합하여 여러 가지 조정이 가능합니다.
// 何も設定しないといい感じに小数点計算してくれる
new Intl.NumberFormat("ja-JP",{ notation: "compact"}).format(BigInt(433333333))
// =>  "4.3億"

// 小数点表記をさせたくなければmaximumFractionDigitsを0にする
new Intl.NumberFormat("ja-JP",{ notation: "compact", maximumFractionDigits:0 }).format(BigInt(433333333))
// => "4億"
// デフォルトでは4桁区切りでカンマを入れる
new Intl.NumberFormat("ja-JP",{ notation: "compact"}).format(BigInt(433333333333333333))
// => "433,333兆"

// この挙動を抑えるにはuseGrouping:falseにする
new Intl.NumberFormat("ja-JP",{ notation: "compact",useGrouping:false}).format(BigInt(433333333333333333))
// => "433333兆"

formatToParts


여기에 formatToParts까지 더하면 이 값들은 따로 받을 수 있다
JSON.stringify(
  new Intl.NumberFormat("ja-JP",{ notation: "compact"})
    .formatToParts(100000), null, 2)
"[
  {
    "type": "integer",
    "value": "10"
  },
  {
    "type": "compact",
    "value": "万"
  }
]"
JSON.stringify(
  new Intl.NumberFormat("ja-JP",{ notation: "compact"})
    .formatToParts(155500000), null, 2)
"[
  {
    "type": "integer",
    "value": "1"
  },
  {
    "type": "decimal",
    "value": "."
  },
  {
    "type": "fraction",
    "value": "6"
  },
  {
    "type": "compact",
    "value": "億"
  }
]"

마지막 타자를 잘 치고 싶다면?


지저분하게 꺼내고 싶을 때는 이 정도면 충분하지만, 더 자세히 꺼내고 싶을 때formatToParts는 시간이 좀 더 걸린다[1]
이번에는 개인적인 취미로 썼어요.while로 기다려도 쓸 수 있겠지?
또 이번 코드는 깊은 검증이 이뤄지지 않았기 때문에 브라우저 등에 따라 행동도 달라질 것으로 예상할 수 있다.
사용 시 주의
function fullFormat(number) {
  const formatter = new Intl.NumberFormat("ja-JP",{ 
    notation: "compact",
    useGrouping: false,
    maximumFractionDigits: 0
  })
  const fmt = (number, result = []) => {
    const bigIntNum = BigInt(number)
    const [num,notation] = formatter.formatToParts(bigIntNum)
    const numStr = bigIntNum.toString()
    if(notation === undefined){
      return [...result, numStr].join("")
    }
    const dig = num.value.length
    const value = numStr.slice(0,dig)
    const next = numStr.slice(dig)
    
    return fmt(next, [...result,`${value}${notation.value}`])
  }
  return fmt(number)
}
는 위에서 말한 바와 같이 maximumFractionDigits: 0와 진행useGrouping:false을 통해 수치만 얻었다.
다만, maximumFractionDigits:0로 설정하면 수치 자체가 반올림되어 사용할 수 없게 되므로 자릿수split로만 잘라내기[2]
그리고 지수 표시가 되면 한순간에 죽기 때문에 빅인트로 전환해야 한다.이 일대에 더 좋은 방법이 있을지도 모른다
이런 느낌의 테스트 코드를 사용해 보세요.
Array.from({ length: 15 }).map((_, i) => {
  const num = BigInt(64 ** i)
  console.log(`64 ** ${i} : ${64 ** i} | ${num} => ${fullFormat(BigInt(64 ** i))}`)
})
64 ** 0 : 1 | 1 => 1
64 ** 1 : 64 | 64 => 64
64 ** 2 : 4096 | 4096 => 4096
64 ** 3 : 262144 | 262144 => 26万2144
64 ** 4 : 16777216 | 16777216 => 1677万7216
64 ** 5 : 1073741824 | 1073741824 => 10億7374万1824
64 ** 6 : 68719476736 | 68719476736 => 687億1947万6736
64 ** 7 : 4398046511104 | 4398046511104 => 4兆3980億4651万1104
64 ** 8 : 281474976710656 | 281474976710656 => 281兆4749億7671万656
64 ** 9 : 18014398509481984 | 18014398509481984 => 18014兆3985億948万1984
64 ** 10 : 1152921504606847000 | 1152921504606846976 => 1152921兆5046億684万6976
64 ** 11 : 73786976294838210000 | 73786976294838206464 => 73786976兆2948億3820万6464
64 ** 12 : 4.722366482869645e+21 | 4722366482869645213696 => 4722366482兆8696億4521万3696
64 ** 13 : 3.022314549036573e+23 | 302231454903657293676544 => 302231454903兆6572億9367万6544
64 ** 14 : 1.9342813113834067e+25 | 19342813113834066795298816 => 19342813113834兆667億9529万8816
눈 검사 후 느낌이 괜찮은 것 같아[3]
각주
일단 유익하든 말든... ↩︎
maximumFractionDigitsformatToParts 사용을 연장할 수 있지만 이렇게 되면 formatter를 다시 초기화할 필요가 있을 것 같아서 포기↩︎
사실 저도 경화 갠지스샤에 출연시켜주고 싶은 마음이 있는데 그 정도는 못 한 것 같아요↩︎

좋은 웹페이지 즐겨찾기