Skip to content

Instantly share code, notes, and snippets.

@amrza
Last active July 27, 2022 13:33
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save amrza/c7e8471c5d07533e009557fb44c3c2e7 to your computer and use it in GitHub Desktop.
Save amrza/c7e8471c5d07533e009557fb44c3c2e7 to your computer and use it in GitHub Desktop.
Convert numbers to FA/EN
/**
* Convert English numbers to Persian.
*
* @param {string} value
* @return {string} converted string.
*/
function faNumbers(value) {
var englishNumbers = {
'0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
'5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
};
if (typeof value === "number") {
var value = value.toString();
}
return value.split("").reduce(function(result, char) {
if (char in englishNumbers) {
return result + englishNumbers[char]
}
return result + char;
}, "");
}
/**
* Convert Persian/Arabic numbers to English.
*
* @param {string} value
* @return {string} converted string.
*/
function enNumbers(value) {
var persianNumbers = {
'۰': '0', '۱': '1', '۲': '2', '۳': '3', '۴': '4',
'۵': '5', '۶': '6', '۷': '7', '۸': '8', '۹': '9',
// in case you type with arabic keyboard:
'٠': '0', '١': '1', '٢': '2', '٣': '3', '٤': '4',
'٥': '5', '٦': '6', '٧': '7', '٨': '8', '٩': '9'
};
return value.split("").reduce(function(result, char) {
if (char in persianNumbers) {
return result + persianNumbers[char]
}
return result + char;
}, "");
}
var log = console.log;
log(enNumbers("٠١٢٣٤٥٦٧٨٩")); // arabic
log(enNumbers("۰۱۲۳۴۵۶۷۸۹.")); // persian
log(faNumbers("0123456789"));
log(faNumbers("a123.44.51n"));
log(faNumbers("1397/10/01"));
log(faNumbers("1397-03-25"));
log(faNumbers("600,000,000"));
log(faNumbers(1234567890)); // by int input.
@okian
Copy link

okian commented Jun 19, 2018

for (n in englishNumbers) {
    value = value.split(n).join(englishNumbers[n])
}

@nainemom
Copy link

You can do it with playing with charCodes and gets faster result:

function enNumbers(str) {
    str.toString().split('').map(a => {
        const charCode = a.charCodeAt(0)
        if (charCode >= 1776 || charCode <= 1785) { // when charachter is ۰ to ۹ (persian nums)
            return String.fromCharCode(charCode - 1728)
        } else if (charCode >= 1632 && charCode <= 1641) { // when charachter is ٠ to ٩ (arabic nums)
            return String.fromCharCode(charCode - 1584)
        }
        return a
    }).join('')
}

@amrza
Copy link
Author

amrza commented Jun 19, 2018

@nainemom

to be honest, performance was not the goal. i see a code like yours before on internet...
if performance was the gaol, your code could also be improve:

split() is making a new array.
map() is making another array.
and join() is going to iterate over all elements of that array from the start...

this could be written by reduce() to get faster result:

function enNumbers(str) {
  return str.toString().split('').reduce(function(result, char) {
      var charCode = char.charCodeAt(0)
      if (charCode >= 1776 && charCode <= 1785) { // when charachter is ۰ to ۹ (persian nums)
          return result + String.fromCharCode(charCode - 1728)
      } else if (charCode >= 1632 && charCode <= 1641) { // when charachter is ٠ to ٩ (arabic nums)
          return result + String.fromCharCode(charCode - 1584)
      }
      return result + char;
  }, "");
}

but as i say, performance was not the goal; however, now that with your help we found a faster solution, its not a bad idea to use it :)

@amrza
Copy link
Author

amrza commented Jun 19, 2018

@nainemom

and this would be the implementation for converting english numbers to persian:

function faNumbers(str) {
  return str.toString().split('').reduce(function(result, char) {
      var charCode = char.charCodeAt(0)
      if (charCode >= 48 && charCode <= 57) { // when charachter is 0 to 9
          return result + String.fromCharCode(charCode + 1728)
      }
      return result + char;
  }, "");
}

@nainemom
Copy link

nice fix. i also realized that toString method make it slower. maybe helper functions like this should be strict for type of parameters entered by end users.

@amrza
Copy link
Author

amrza commented Jun 19, 2018

@nainemom

toString is not needed for enNumbers(). the value that comes in enNumbers() is always a string. you cant have (۱۲۳).toString(). its always like "۱۲۳" in the first place...
however, its needed for faNumbers(). the (123).toString is actually a possible value.

and also, the || should be && in the first if. i upload a whole new script based on your solution:

https://gist.github.com/amrza/9b5940b102286f9f37160b5e2b7e81a0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment