Format numbers helper (#14186)
format number to 100000 -> 100k/ 1000000000 -> 1b/ 1000000 -> 1m
This commit is contained in:
parent
7b739dff45
commit
bca2258508
|
@ -1,4 +1,6 @@
|
|||
(ns status-im.utils.number)
|
||||
(ns status-im.utils.number
|
||||
(:require [goog.string :as gstring]
|
||||
[goog.string.format]))
|
||||
|
||||
(defn naive-round
|
||||
"Quickly and naively round number `n` up to `decimal-places`.
|
||||
|
@ -13,3 +15,61 @@
|
|||
(let [scale (Math/pow 10 decimal-places)]
|
||||
(/ (Math/round (* n scale))
|
||||
scale)))
|
||||
|
||||
(defn- caught-invalid-number []
|
||||
(throw (js/Error "Invalid Number")))
|
||||
|
||||
(defn- with-precision [precision input-number]
|
||||
(gstring/format (str "%." precision "f") input-number))
|
||||
|
||||
(defn- is-bad-number [number-string]
|
||||
(nil? (re-find #"^\d+(\.\d{1,9})?$" number-string)))
|
||||
|
||||
(defn- with-precision-division [numerator-num denominator-num precision]
|
||||
(->> (/ numerator-num denominator-num)
|
||||
(with-precision precision)))
|
||||
|
||||
(defn- number->formatted-number [number-string precision]
|
||||
(let [parsed-number (js/parseInt number-string 10)
|
||||
numeric-value (if (or (neg? number-string)
|
||||
(is-bad-number (str number-string)))
|
||||
(caught-invalid-number)
|
||||
parsed-number)
|
||||
million 1000000
|
||||
billion 1000000000
|
||||
>=-and-< #(and
|
||||
(>= %1 %2)
|
||||
(< %1 %3))
|
||||
unit (cond
|
||||
(>=-and-< parsed-number billion js/Number.MAX_SAFE_INTEGER) "b"
|
||||
(>=-and-< parsed-number million billion) "m"
|
||||
:else
|
||||
"k")
|
||||
denominator (cond
|
||||
(= unit "m") million
|
||||
(= unit "b") billion
|
||||
:else 1000)]
|
||||
(if (js/isNaN numeric-value)
|
||||
(caught-invalid-number)
|
||||
(if (>= numeric-value 1000)
|
||||
(str (with-precision-division numeric-value denominator precision)
|
||||
unit)
|
||||
(str numeric-value)))))
|
||||
|
||||
(defn format-number
|
||||
"Returns the thousands in a number in kilo format
|
||||
|
||||
Arguments:
|
||||
|
||||
number-string (or string int) The input of value of the number
|
||||
|
||||
Examples:
|
||||
[1000 0] -> 1k
|
||||
[1001 0] -> 1k
|
||||
[10000 0] -> 10k
|
||||
[5000 0] -> 5k
|
||||
[5000 0] -> 5k
|
||||
[5000000 0] -> 5m
|
||||
[5000 0] -> 5k"
|
||||
[number-string precision]
|
||||
(number->formatted-number number-string precision))
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
(ns status-im.utils.number-test
|
||||
(:require [cljs.test :refer-macros [deftest testing are]]
|
||||
[status-im.utils.number :as number]))
|
||||
|
||||
(deftest format-number-test
|
||||
(testing "Positive cases"
|
||||
(are [input-number precision expected] (= (number/format-number input-number precision) expected)
|
||||
"100" 0 "100"
|
||||
"1000" 0 "1k"
|
||||
"10000" 0 "10k"
|
||||
"11000" 1 "11.0k"
|
||||
"11000" 0 "11k"
|
||||
"11010" 3 "11.010k"
|
||||
"5200000" 3 "5.200m"
|
||||
"1000000000" 0 "1b"
|
||||
"1110000000" 2 "1.11b"
|
||||
"9000000" 0 "9m"))
|
||||
(testing "Negative cases"
|
||||
(are [input-number precision] (thrown-with-msg? js/Error #"Invalid Number" (number/format-number input-number precision))
|
||||
js/undefined 0
|
||||
nil 0
|
||||
"-1" 0
|
||||
"" 0
|
||||
js/NaN 0
|
||||
"1e3" 0
|
||||
"10,2" 0
|
||||
"6hello" 0)))
|
Loading…
Reference in New Issue