From 82b1b03dec10dd96bd925f08cd8d306ac1014f4d Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 23 Apr 2021 18:28:20 +0430 Subject: [PATCH] fix(wordsToNumber): make it functional --- README.md | 26 +++---- src/index.ts | 2 +- src/modules/wordsToNumber/index.ts | 112 +++++++++++++---------------- test/wordsToNumber.spec.ts | 54 +++++++------- 4 files changed, 92 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 922ca439..8f4d7154 100755 --- a/README.md +++ b/README.md @@ -103,31 +103,31 @@ Let's take a look at what an example test case would look like using Persian-too | `addCommas` | Commas will be added to the Result | `false` - Convert with no option ```javascript -import { WordsToNumber } from "@persian-tools/persian-tools"; +import { wordsToNumber } from "@persian-tools/persian-tools"; -WordsToNumber.convert("منفی سه هزارمین") // -3000 -WordsToNumber.convert("منفی سه هزارم") // -3000 -WordsToNumber.convert("منفی سه هزار") // -3000 -WordsToNumber.convert("سه هزار دویست و دوازده") // 3212 -WordsToNumber.convert("دوازده هزار بیست دو") // 12022 +wordsToNumber("منفی سه هزارمین") // -3000 +wordsToNumber("منفی سه هزارم") // -3000 +wordsToNumber("منفی سه هزار") // -3000 +wordsToNumber("سه هزار دویست و دوازده") // 3212 +wordsToNumber("دوازده هزار بیست دو") // 12022 ``` - Digits converter ```js -WordsToNumber.convert("منفی سه هزارمین", { digits: "fa" }) // "-۳۰۰۰" -WordsToNumber.convert("دوازده هزار بیست دو", { digits: "fa" }) // ۱۲۰۲۲ +wordsToNumber("منفی سه هزارمین", { digits: "fa" }) // "-۳۰۰۰" +wordsToNumber("دوازده هزار بیست دو", { digits: "fa" }) // ۱۲۰۲۲ ``` - Add commas ```js -WordsToNumber.convert("منفی سه هزارمین", { addCommas: true }) // "-3,000" -WordsToNumber.convert("دوازده هزار بیست دو", { addCommas: true }) // "12,022" +wordsToNumber("منفی سه هزارمین", { addCommas: true }) // "-3,000" +wordsToNumber("دوازده هزار بیست دو", { addCommas: true }) // "12,022" ``` - Fuzzy typo fixer(`v1.5.0`): ```javascript import { WordsToNumber } from "@persian-tools/persian-tools"; -WordsToNumber.convert("یگصد و بنجاه هزار", { fuzzy: true }) // "150000" -WordsToNumber.convert("دویشت ر بیشت هزار", { fuzzy: true }) // "220000" -WordsToNumber.convert("منقی ضد", { fuzzy: true }) // "-100" +wordsToNumber("یگصد و بنجاه هزار", { fuzzy: true }) // "150000" +wordsToNumber("دویشت ر بیشت هزار", { fuzzy: true }) // "220000" +wordsToNumber("منقی ضد", { fuzzy: true }) // "-100" ``` ### Convert Numbers to Persian words diff --git a/src/index.ts b/src/index.ts index afaa2872..ade42b9b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,7 @@ export { isPersian, hasPersian } from "./modules/isPersian"; export { default as toPersianChars } from "./modules/toPersianChars"; // String and Number Converter and their utilities export { default as NumberToWords, NumberToWordsOptions } from "./modules/numberToWords"; -export { default as WordsToNumber, WordsToNumberOptions } from "./modules/wordsToNumber"; +export { default as wordsToNumber, WordsToNumberOptions } from "./modules/wordsToNumber"; export { default as removeOrdinalSuffix } from "./modules/removeOrdinalSuffix"; export { default as addOrdinalSuffix } from "./modules/addOrdinalSuffix/addOrdinalSuffix"; // Add and Remove Commas diff --git a/src/modules/wordsToNumber/index.ts b/src/modules/wordsToNumber/index.ts index 3662906c..dd291c4b 100644 --- a/src/modules/wordsToNumber/index.ts +++ b/src/modules/wordsToNumber/index.ts @@ -23,76 +23,66 @@ export interface WordsToNumberOptions { fuzzy?: boolean; } -class WordsToNumber { - /** - * Convert to numbers - * - * @method WordsToNumber - * @param {string} words - * @param {WordsToNumberOptions} options - * @return Converted words to number. e.g: 350000 - */ - convert( - words: string, - { digits = "en", addCommas: shouldAddCommas = false, fuzzy: isEnabledFuzzy = false }: WordsToNumberOptions = {}, - ): TResult { - if (!words) return "" as TResult; +function compute(tokens: string[]): number { + let sum = 0; + let isNegative = false; - // Remove ordinal suffixes - words = words.replace(new RegExp("مین$", "ig"), ""); - words = removeOrdinalSuffix(words)!; - // Fix Persian typo's if enabled if this option is enabled - const classified = isEnabledFuzzy ? fuzzy(words) : words; - const computeNumbers = this.compute(this.tokenize(classified!)); - const addCommasIfNeeded: string | number = shouldAddCommas - ? addCommas(computeNumbers) - : (computeNumbers as number); + tokens.forEach((token) => { + token = digitsFaToEn(token)!; - if (digits === "fa") { - return digitsEnToFa(addCommasIfNeeded) as TResult; - } else if (digits === "ar") { - return digitsEnToAr(addCommasIfNeeded) as TResult; + if (token === PREFIXES[0]) { + isNegative = true; + } else if (UNITS[token] != null) { + sum += UNITS[token]; + } else if (TEN[token] != null) { + sum += TEN[token]; + } else if (!isNaN(Number(token))) { + sum += parseInt(token, 10); } else { - return addCommasIfNeeded as TResult; + sum *= MAGNITUDE[token]; } + }); + return isNegative ? sum * -1 : sum; +} - return (digits === "fa" ? digitsEnToFa(addCommasIfNeeded) : addCommasIfNeeded) as TResult; - } - private tokenize(words: string): string[] { - words = replaceArray(words, TYPO_LIST); +function tokenize(words: string): string[] { + words = replaceArray(words, TYPO_LIST); - const result: string[] = []; - const slittedWords: string[] = words.split(" "); - slittedWords.forEach((word) => { - return word === JOINERS[0] ? "" : result.push(word); - }); + const result: string[] = []; + const slittedWords: string[] = words.split(" "); + slittedWords.forEach((word) => { + return word === JOINERS[0] ? "" : result.push(word); + }); - return result; - } + return result; +} - private compute(tokens: string[]): number { - let sum = 0; - let isNegative = false; +/** + * + * Convert to numbers + * + * @category Number conversion + * @return Converted words to number. e.g: 350000 + */ +export default function wordsToNumber( + words: string, + { digits = "en", addCommas: shouldAddCommas = false, fuzzy: isEnabledFuzzy = false }: WordsToNumberOptions = {}, +): TResult { + if (!words) return "" as TResult; - tokens.forEach((token) => { - token = digitsFaToEn(token)!; + // Remove ordinal suffixes + words = words.replace(new RegExp("مین$", "ig"), ""); + words = removeOrdinalSuffix(words)!; + // Fix Persian typo's if enabled if this option is enabled + const classified = isEnabledFuzzy ? fuzzy(words) : words; + const computeNumbers = compute(tokenize(classified!)); + const addCommasIfNeeded: string | number = shouldAddCommas ? addCommas(computeNumbers) : (computeNumbers as number); - if (token === PREFIXES[0]) { - isNegative = true; - } else if (UNITS[token] != null) { - sum += UNITS[token]; - } else if (TEN[token] != null) { - sum += TEN[token]; - } else if (!isNaN(Number(token))) { - sum += parseInt(token, 10); - } else { - sum *= MAGNITUDE[token]; - } - }); - return isNegative ? sum * -1 : sum; + if (digits === "fa") { + return digitsEnToFa(addCommasIfNeeded) as TResult; + } else if (digits === "ar") { + return digitsEnToAr(addCommasIfNeeded) as TResult; + } else { + return addCommasIfNeeded as TResult; } } - -const WordsToNumberInstance = new WordsToNumber(); - -export default WordsToNumberInstance; diff --git a/test/wordsToNumber.spec.ts b/test/wordsToNumber.spec.ts index 99850016..189307fc 100644 --- a/test/wordsToNumber.spec.ts +++ b/test/wordsToNumber.spec.ts @@ -1,76 +1,76 @@ -import { WordsToNumber } from "../src"; +import { wordsToNumber } from "../src"; -describe("WordsToNumber", () => { +describe("wordsToNumber", () => { it("Should convert truly", () => { - expect(WordsToNumber.convert("منفی سه هزار")).toEqual(-3000); - expect(WordsToNumber.convert("سه هزار دویست و دوازده")).toEqual(3212); - expect(WordsToNumber.convert("دوازده هزار بیست دو")).toEqual(12022); + expect(wordsToNumber("منفی سه هزار")).toEqual(-3000); + expect(wordsToNumber("سه هزار دویست و دوازده")).toEqual(3212); + expect(wordsToNumber("دوازده هزار بیست دو")).toEqual(12022); expect( - WordsToNumber.convert("دوازده هزار بیست دو", { addCommas: true }), + wordsToNumber("دوازده هزار بیست دو", { addCommas: true }), ).toEqual("12,022"); expect( - WordsToNumber.convert("دوازده هزار و بیست و دو", { addCommas: true }), + wordsToNumber("دوازده هزار و بیست و دو", { addCommas: true }), ).toEqual("12,022"); }); it("Should convert truly and convert to Arabic digits", () => { expect( - WordsToNumber.convert("منفی سه هزار", { digits: "ar" }), + wordsToNumber("منفی سه هزار", { digits: "ar" }), ).toEqual("-۳۰۰۰"); expect( - WordsToNumber.convert("سه هزار دویست و دوازده", { digits: "ar" }), + wordsToNumber("سه هزار دویست و دوازده", { digits: "ar" }), ).toEqual("۳۲۱۲"); expect( - WordsToNumber.convert("دوازده هزار بیست دو", { digits: "ar" }), + wordsToNumber("دوازده هزار بیست دو", { digits: "ar" }), ).toEqual("۱۲۰۲۲"); expect( - WordsToNumber.convert("دوازده هزار بیست دو", { digits: "ar", addCommas: true }), + wordsToNumber("دوازده هزار بیست دو", { digits: "ar", addCommas: true }), ).toEqual("۱۲,۰۲۲"); expect( - WordsToNumber.convert("دوازده هزار و بیست و دو", { digits: "ar", addCommas: true }), + wordsToNumber("دوازده هزار و بیست و دو", { digits: "ar", addCommas: true }), ).toEqual("۱۲,۰۲۲"); expect( - WordsToNumber.convert("چهارصد پنجاه هزار", { digits: "ar", addCommas: true }), + wordsToNumber("چهارصد پنجاه هزار", { digits: "ar", addCommas: true }), ).toEqual("٤٥۰,۰۰۰"); expect( - WordsToNumber.convert("چهارصد پنجاه هزار", { digits: "ar" }), + wordsToNumber("چهارصد پنجاه هزار", { digits: "ar" }), ).toEqual("٤٥۰۰۰۰"); }); it("Should convert with ordinal words", () => { expect( - WordsToNumber.convert("منفی ۳ هزار", { digits: "fa", addCommas: true }), + wordsToNumber("منفی ۳ هزار", { digits: "fa", addCommas: true }), ).toEqual("-۳,۰۰۰"); expect( - WordsToNumber.convert("منفی 3 هزار و 200", { digits: "fa", addCommas: true }), + wordsToNumber("منفی 3 هزار و 200", { digits: "fa", addCommas: true }), ).toEqual("-۳,۲۰۰"); expect( - WordsToNumber.convert("منفی سه هزارمین", { digits: "fa", addCommas: true }), + wordsToNumber("منفی سه هزارمین", { digits: "fa", addCommas: true }), ).toEqual("-۳,۰۰۰"); expect( - WordsToNumber.convert("منفی سه هزارمین", { digits: "fa" }), + wordsToNumber("منفی سه هزارمین", { digits: "fa" }), ).toEqual("-۳۰۰۰"); - expect(WordsToNumber.convert("منفی سه هزارمین")).toEqual(-3000); - expect(WordsToNumber.convert("منفی سه هزارم")).toEqual(-3000); - expect(WordsToNumber.convert("منفی سه هزارمین")).not.toEqual("-3000"); - expect(String(WordsToNumber.convert("منفی سه هزارمین"))).toHaveLength(5); - expect(WordsToNumber.convert("منفی سی اُم")).toEqual(-30); + expect(wordsToNumber("منفی سه هزارمین")).toEqual(-3000); + expect(wordsToNumber("منفی سه هزارم")).toEqual(-3000); + expect(wordsToNumber("منفی سه هزارمین")).not.toEqual("-3000"); + expect(String(wordsToNumber("منفی سه هزارمین"))).toHaveLength(5); + expect(wordsToNumber("منفی سی اُم")).toEqual(-30); expect( - WordsToNumber.convert("سی و سوم", { fuzzy: true }), + wordsToNumber("سی و سوم", { fuzzy: true }), ).toEqual(33); }); it("Should return undefined", () => { expect( - WordsToNumber.convert("", { digits: "fa", addCommas: true }), + wordsToNumber("", { digits: "fa", addCommas: true }), ).toEqual(""); // @ts-ignore - expect(WordsToNumber.convert()).toEqual(""); + expect(wordsToNumber()).toEqual(""); }); it("Should works with fuzzy model", () => { expect( - WordsToNumber.convert("ضد و بنچاه و دو", { fuzzy: true }), + wordsToNumber("ضد و بنچاه و دو", { fuzzy: true }), ).toEqual(152); }); });