Format numbers helper (#14186)

format number to 100000 -> 100k/ 1000000000 -> 1b/ 1000000 -> 1m
This commit is contained in:
Ibrahem Khalil 2022-11-03 10:33:34 +03:00 committed by GitHub
parent 7b739dff45
commit bca2258508
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 1 deletions

View File

@ -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))

View File

@ -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)))