Last active
November 25, 2020 03:12
-
-
Save VassilisPallas/d73632e9de4794b7dd10b7408f7948e8 to your computer and use it in GitHub Desktop.
Equivalent to PHP function number_format in Javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert'); | |
const numberFormat = require('./numberFormat'); | |
assert.strictEqual( | |
numberFormat(132323232320.321, 2, ',', '.'), | |
'132.323.232.320,32' | |
); | |
assert.strictEqual( | |
numberFormat(10.22), | |
'10.22' | |
); | |
assert.strictEqual( | |
numberFormat(100), | |
'100' | |
); | |
assert.strictEqual( | |
numberFormat(1000, 2, ',', '.'), | |
'1.000,00' | |
); | |
assert.strictEqual( | |
numberFormat(95**12, 2), | |
'540,360,087,662,636,990,201,856' | |
); | |
assert.strictEqual( | |
numberFormat(123e5, 2), | |
'12,300,000.00' | |
); | |
assert.strictEqual( | |
numberFormat(123e5), | |
'12,300,000' | |
); | |
assert.strictEqual( | |
numberFormat(123e-5), | |
'0.00' | |
); | |
assert.strictEqual( | |
numberFormat(123e-15), | |
'0' | |
); | |
assert.strictEqual( | |
numberFormat(123e-15, 15), | |
'0.000000000000123' | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const splitThousands = (number) => (dec_point, thousands_point) => { | |
const splitNum = number.toString().split(dec_point); | |
splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_point); | |
return splitNum.join(dec_point); | |
}; | |
const isBigNumber = (number) => number.toString().includes("e"); | |
const isBigFloat = (number) => number.toString().includes("-"); | |
const calcTrailing = (dec, len) => Number(dec) + 2 - len; | |
const handleBigFloats = (number, decimals) => { | |
if (!decimals) { | |
return "0"; | |
} | |
const [numbers, dec] = number.toString().replace(".", "").split("e-"); | |
const trailingZeros = calcTrailing(dec, numbers.length); | |
const res = `${"0.".padEnd(trailingZeros + 2, "0")}${numbers}`; | |
return decimals ? res.substring(0, 2) + res.substring(2, decimals + 2) : res; | |
}; | |
const handleBigNumbers = (number, decimals, dec_point, thousands_point) => { | |
if (isBigFloat(number)) { | |
return handleBigFloats(number, decimals); | |
} | |
return splitThousands(BigInt(number))(dec_point, thousands_point); | |
}; | |
function handleFiniteNumbers(number, decimals, dec_point, thousands_point) { | |
if (!isFinite(number)) { | |
throw new TypeError("number is not finite number"); | |
} | |
if (!decimals) { | |
const len = number.toString().split(".").length; | |
decimals = len > 1 ? len : 0; | |
} | |
return splitThousands( | |
parseFloat(number).toFixed(decimals).replace(".", dec_point) | |
)(dec_point, thousands_point); | |
} | |
const numberFormat = ( | |
number, | |
decimals, | |
dec_point = ".", | |
thousands_point = "," | |
) => { | |
if (number == null || typeof number !== "number") { | |
throw new TypeError("number is not valid"); | |
} | |
if (isBigNumber(number)) { | |
return handleBigNumbers(number, decimals, dec_point, thousands_point); | |
} | |
return handleFiniteNumbers(number, decimals, dec_point, thousands_point); | |
}; | |
module.exports = numberFormat; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment