diff --git a/README.md b/README.md
index 6487091..a3527b0 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ No specific version of nodejs and npm is required, but for the usage as an npm p
- [Common Utilities](#common-utils)
- [removeByKey](#remove-by-key)
- [removeDeepByKey](#remove-deep-by-key)
+ - [beautifyNumber](#beautify-number)
- [List Utils](#list-utils)
- [findByPrimaryKey](#find-by-primary-key)
- [Contributing](#contributing)
@@ -212,6 +213,42 @@ const result = removeDeepByKey(['c'], target); -> { a: 'a', b: 'B' }
const targetEqualsResult = result === target; -> true
```
+#### beautifyNumber()
+
+```ts
+beautifyNumber(value: number, options: IBeautifyNumberOptions);
+```
+
+Produces a formatted string that was created out of the number provided as an input of the function.
+Formatting rules:
+
+- splits a whole part of a number by thousands
+- adds a `joint` symbol between thousands
+- adds a `delimiter` symbol between a whole and a floating part
+
+#### Options
+
+| Name | Type | Required | Default value |
+| ------- | ------------------------ | -------- | -------------------------------- |
+| value | `number` | + | - |
+| options | `IBeautifyNumberOptions` | - | `{ delimiter: '.', joint: ' ' }` |
+
+Examples:
+
+```ts
+// Whole numbers
+const result = beautifyNumber(1000); -> '1 000'
+const result = beautifyNumber(1_000); -> '1 000'
+
+// With floating point
+const result = beautifyNumber(1000.123); -> '1 000.123'
+const result = beautifyNumber(1000.123, { delimiter: ',' }); -> '1 000,123'
+const result = beautifyNumber(1000.123, { delimiter: ',', joint: '_' }); -> '1_000,123'
+
+// Throws error
+const result = beautifyNumber(1000.123, { delimiter: ',', joint: ',' }); -> [Error: Please provide different delimiter and joint values]
+```
+
### List Utils
A common function for initializing a bag of useful traversing utilities for going over, finding and mutating nodes within some nested objects structures.
@@ -228,6 +265,7 @@ Might be useful if you want to create a set of handy functions at one place, bin
| initOptions | `IInitListUtilsOptions` | + | - |
##### `IInitListUtilsOptions`
+
| Property | Type | Default value |
| ----------- | -------- | ------------- |
| primaryKey | `string` | - |
diff --git a/package.json b/package.json
index 17c48a6..5deda18 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "handilities",
- "version": "0.0.6",
+ "version": "0.0.7",
"description": "Handy utilities for JS, TS, React in browser and server env",
"main": "lib",
"scripts": {
diff --git a/src/common/__tests__/beautifyNumber.test.ts b/src/common/__tests__/beautifyNumber.test.ts
new file mode 100644
index 0000000..d877bab
--- /dev/null
+++ b/src/common/__tests__/beautifyNumber.test.ts
@@ -0,0 +1,77 @@
+import { sameJointAndDelimiterErrorMessage, beautifyNumber } from "../beautifyNumber";
+
+describe("beautifyNumber", () => {
+ describe("beautifyNumber with no options passed", () => {
+ test.each([
+ [1, "1"],
+ [100, "100"],
+ [1000, "1 000"],
+ [100000, "100 000"],
+ [123456789, "123 456 789"],
+ ])('converts "%s" into "%s"', (value, result) => {
+ expect(beautifyNumber(value)).toBe(result);
+ });
+ });
+
+ describe('beautifyNumber with the "," joint', () => {
+ test.each([
+ [1, "1"],
+ [100, "100"],
+ [1000, "1,000"],
+ [100000, "100,000"],
+ [123456789, "123,456,789"],
+ ])('converts "%s" into "%s"', (value, result) => {
+ expect(beautifyNumber(value, { joint: "," })).toBe(result);
+ });
+ });
+
+ describe("beautifyNumber for floating numbers", () => {
+ test.each([
+ [1.12, "1.12"],
+ [100.123, "100.123"],
+ [1000.1234, "1 000.1234"],
+ [100000.12345, "100 000.12345"],
+ [123456789.0123456, "123 456 789.0123456"],
+ ])('converts "%s" into "%s"', (value, result) => {
+ expect(beautifyNumber(value)).toBe(result);
+ });
+ });
+
+ describe('beautifyNumber for floating numbers with the "_" joint, and "," delimiter', () => {
+ test.each([
+ [1.12, "1,12"],
+ [100.123, "100,123"],
+ [1000.1234, "1_000,1234"],
+ [100000.12345, "100_000,12345"],
+ [123456789.0123456, "123_456_789,0123456"],
+ ])('converts "%s" into "%s"', (value, result) => {
+ expect(beautifyNumber(value, { joint: "_", delimiter: "," })).toBe(result);
+ });
+ });
+
+ describe("beautifyNumber for negative floating numbers", () => {
+ test.each([
+ [-1.12, "-1.12"],
+ [-100.123, "-100.123"],
+ [-1000.1234, "-1 000.1234"],
+ [-100000.12345, "-100 000.12345"],
+ [-123456789.0123456, "-123 456 789.0123456"],
+ ])('converts "%s" into "%s"', (value, result) => {
+ expect(beautifyNumber(value)).toBe(result);
+ });
+ });
+
+ test('works for "_" number notation', () => {
+ expect(beautifyNumber(12_001_123)).toBe("12 001 123");
+ });
+
+ test("throws the error if joint and delimiter are equal", () => {
+ try {
+ beautifyNumber(12_001_123, { joint: "", delimiter: "" });
+ } catch (error) {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ expect(error.message).toContain(sameJointAndDelimiterErrorMessage);
+ }
+ });
+});
diff --git a/src/common/beautifyNumber.ts b/src/common/beautifyNumber.ts
new file mode 100644
index 0000000..9278074
--- /dev/null
+++ b/src/common/beautifyNumber.ts
@@ -0,0 +1,37 @@
+interface IBeautifyNumberOptions {
+ delimiter?: string;
+ joint?: string;
+}
+
+interface IBeautifyNumber {
+ (value: number, options?: IBeautifyNumberOptions): string;
+}
+
+const sameJointAndDelimiterErrorMessage = "Please provide different delimiter and joint values";
+
+const DEFAULT_DELIMITER = ".";
+const DEFAULT_JOINT = " ";
+
+/**
+ *
+ * @param value number to format based on options
+ * @param options "joint" symbol to add between thousands, and "delimiter" symbol to join whole and floating parts
+ * @returns string produced out of a formatted number
+ */
+const beautifyNumber: IBeautifyNumber = (value, options = {}) => {
+ const { delimiter = DEFAULT_DELIMITER, joint = DEFAULT_JOINT } = options;
+
+ if (delimiter === joint) {
+ const error = new Error(sameJointAndDelimiterErrorMessage);
+
+ throw error;
+ }
+
+ const [whole, decimal] = String(value).split(".");
+ const wholeWithJoint = whole.replace(/\B(?=(\d{3})+(?!\d))/g, joint);
+
+ return decimal ? `${wholeWithJoint}${delimiter}${decimal}` : wholeWithJoint;
+};
+
+export type { IBeautifyNumber, IBeautifyNumberOptions };
+export { sameJointAndDelimiterErrorMessage, beautifyNumber };
diff --git a/src/common/index.ts b/src/common/index.ts
index eb9dc28..4ef6202 100644
--- a/src/common/index.ts
+++ b/src/common/index.ts
@@ -6,3 +6,6 @@ export type { IRemoveByKey } from "./removeByKey";
export { initListUtils, findByPrimaryKey } from "./list-utils";
export type { IInitListUtilsOptions, IFindByPrimaryKeyMutation } from "./list-utils";
+
+export { beautifyNumber } from "./beautifyNumber";
+export type { IBeautifyNumber, IBeautifyNumberOptions } from "./beautifyNumber";