首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >印度编号系统-转换为正式和通用的编号系统字/字符串

印度编号系统-转换为正式和通用的编号系统字/字符串
EN

Code Review用户
提问于 2020-08-01 23:31:14
回答 1查看 1.3K关注 0票数 3

我开发了以下简短的JavaScript函数来将数字转换为印度的编号系统格式;官方编号系统和通用系统(即使用Lakh-Crore系统)都使用将数字转换为Siptlet和Duplet字符串的方法。

基于这篇解释印度编号系统的wiki文章,我创建了下面的汇总表,它将同样的汇总表转换成一个步骤/流逻辑,然后可以转换成适当的代码。

因此,基于以上(以及我对主题的理解),我制定了下面的JavaScript函数来处理:

  1. 官方编号系统,以及
  2. 通用编号系统,以及
  3. 如果需要的话,印度货币。

我已经尝试(尽可能)使用ES6关键字和函数。

在生成通用文本时,在每个Siptlet文本之间插入一个“逗号”,因为输出很长,很难理解。但是,如果不需要,可以在代码的第8行删除这个逗号。

我还包括两个测试用例代码来测试两个编号系统。

该函数可按以下方式为通用用途调用:

要转换的数字可以作为数字或字符串传递。

代码语言:javascript
复制
integerToWordsInd("2222300000"));       // Two hundred Twenty-Two Crore, Twenty-Three Lakh

至于官方系统:

代码语言:javascript
复制
integerToWordsInd ("2222300000",true);  // Two Arab Twenty-Two Crore Twenty-Three Lakh

另外还添加了一个函数numberCurrencyInd(),将数字转换为印度货币“卢比和比萨”,并可以使用官方或通用系统作为使用调用参数的选项(类似于数字转换函数)。

它还可以作为一个例子,说明如何调用数字的整个部分和数字的小数部分的函数。

代码语言:javascript
复制
numberCurrencyIn(3002900000.50);         //Three Hundred Crore, Twenty-Nine Lakh Rupees and Fifty Paisa

// or

numberCurrencyIn(3002900000.50,true);    // Three Arab Twenty-Nine Lakh Rupees and Fifty Paisa

在这两种系统下,增加了两(2)种测试货币生成的rest情况。

这些职能的内部工作如下:

下一行将数字转换为Siptlet (7s)的数组元素(固定大小为7位),以便在通用编号系统中使用:

代码语言:javascript
复制
Num = ("0".repeat(6*(Num+="").length % 7) +Num).match(/.{7}/g);

下一行将数字转换为一个三重奏的数组元素,然后是Duplet,以便在正式和通用的编号系统中使用:

代码语言:javascript
复制
Num = Num> 999 ? [...(Num.slice(0,-3).match(/.{2}/g).map(e => "0"+e)),(Num.slice(-3))] :
                  [("00"+Num).substr(-3)];

如果请求通用系统,则首先将数字转换为Siptlet (7's),然后为每个Siptlet调用内部函数,使用Triplet/Duplet生成单词。

但是,如果请求正式系统,则立即调用内部函数来生成使用Triplet/Duplets的单词。

代码语言:javascript
复制
/*********************************************************************
* @function    : integerToWordsInd()
* @purpose     : Converts Unsigned Integers to Indian Numeral Words
*                With options for either the Official or the
*                Crore-Lakh Counting Systems
* @version     : 1.00
* @author      : Mohsen Alyafei
* @date        : 07 July 2020
* @param       : {number} [integer numeric or string]
* @param       : Optional {boolean} [Official]
*                      0     = Use Crore-Lakh Counting System (default)
*                      Non 0 = Use the Official System
* @returns     : {string} The wordified number string
**********************************************************************/
var Table_0_19 = ["","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"],
    Table_20_90= ["","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"],
    Table_Scale= ["","Thousand","Lakh","Crore","Arab","Kharab","Neel","Padma","Shankh","Samudra","Antya","Madhyam","Paraardh","***","***"];
//===================================================================
function integerToWordsInd(Num=0 , Official=0) {
if (Num===0) return "Zero";
if (Official) return Siptlets(Num);                   // Return Official Numbering System text
let NumWords="";
Num = ("0".repeat(6*(Num+="").length % 7) +Num).match(/.{7}/g); // Create Siptlets Array
return Num.map((Siptlet, ScalePos) => {               // Return Commmon-Use Numbering System text
  let [Scale,SWords] = [(Table_Scale[3]+" ").repeat(Num.length-ScalePos-1).trimRight(), Siptlets(Siptlet)];
  NumWords +=(NumWords && SWords ? ", " : "") +SWords +(Scale ? " " : "") +Scale;
}), NumWords;
//===================================================================
function Siptlets(Num, NumWords="") {                 // Core function (Called for both Systems)
(Num+="").length-3 & 1 && (Num="0"+Num);
Num = Num> 999 ? [...Num.slice(0,-3).match(/.{2}/g).map(e => "0"+e),(Num.slice(-3))]:[("00"+Num).substr(-3)];
return Num.map((Duplet,ScalePos) => {if (+Duplet) {
let [Hyphen,Hundreds,Tens,Scale] = [+Duplet[2] ? "-" : "",+Duplet[0],+Duplet.substr(1),Table_Scale[Num.length-ScalePos-1]];
NumWords  += (NumWords          ? " " : "") + (Hundreds ? Table_0_19[Hundreds] + " Hundred" :"") +
             (Hundreds && Tens  ? " " : "") + (Tens< 20 ? Table_0_19[Tens] :
             Table_20_90[+(Duplet[1])]      + Hyphen    + Table_0_19[+Duplet[2]]);
NumWords  += (NumWords && Scale ? " " : "") + Scale;
}}), NumWords;}
}
//===================================================================




//===================================================================
//      Extra Function if needed for Indian Currency
// Uses same input parameters as the above main function
//===================================================================
function numberCurrencyIn(Num=0 , Official=0) {
let n= (Num+"").split(0.1.toLocaleString().substr(1,1)); // Number and Fraction parts
n.length!==2 && (n[1]= ""); // No fraction
Num= n[0];
let Nw="", Fw="", Frc = (n[1]+"00").substring(0,2); // Limit to 2 Decimal Places
Num && (Nw= integerToWordsInd(Num,Official));       // Convert the Whole Number
Frc && (Fw= integerToWordsInd(Frc,Official));       // Convert the Fractional Part
return (Nw ? Nw:"") + (Nw ? " Rupees":"") + (Nw && Fw ? " and ":"") + (Fw ? Fw+" Paisa":""); // Join together
}
//===================================================================



//===================================================================
//                     Test Cases
//===================================================================
// 1. Test Numbers under Common-Use Numbering System
//===================================================================
var r=0; // test tracker
r |= testN(50,"Fifty");
r |= testN(12000,"Twelve Thousand");
r |= testN(777000,"Seven Lakh Seventy-Seven Thousand");
r |= testN(550001,"Five Lakh Fifty Thousand One");
r |= testN(12345678,"One Crore, Twenty-Three Lakh Forty-Five Thousand Six Hundred Seventy-Eight");
r |= testN(123456789,"Twelve Crore, Thirty-Four Lakh Fifty-Six Thousand Seven Hundred Eighty-Nine");
r |= testN(1234567890,"One Hundred Twenty-Three Crore, Forty-Five Lakh Sixty-Seven Thousand Eight Hundred Ninety");
r |= testN(12345678900,"One Thousand Two Hundred Thirty-Four Crore, Fifty-Six Lakh Seventy-Eight Thousand Nine Hundred");
if (r==0) console.log("Test Case 1 Numbers (Common-Use Numbering System) Passed.");
//===================================================================
// 2. Test Numbers under Official Numbering System
//===================================================================
var r=0; // test tracker
r |= testN(50,"Fifty");
r |= testN(12000,"Twelve Thousand",true);
r |= testN(777000,"Seven Lakh Seventy-Seven Thousand",true);
r |= testN(550001,"Five Lakh Fifty Thousand One",true);
r |= testN(12345678,"One Crore Twenty-Three Lakh Forty-Five Thousand Six Hundred Seventy-Eight",true);
r |= testN(123456789,"Twelve Crore Thirty-Four Lakh Fifty-Six Thousand Seven Hundred Eighty-Nine",true);
r |= testN(1234567890,"One Arab Twenty-Three Crore Forty-Five Lakh Sixty-Seven Thousand Eight Hundred Ninety",true);
r |= testN(12345678900,"Twelve Arab Thirty-Four Crore Fifty-Six Lakh Seventy-Eight Thousand Nine Hundred",true);
if (r==0) console.log("Test Case 2 Numbers (Official Numbering System) Passed.");
//===================================================================
// 3. Test Currency under Common-Use Numbering System
//===================================================================
var r=0; // test tracker
r |= testC(1,"One Rupees");
r |= testC(2.0,"Two Rupees");
r |= testC(2.01,"Two Rupees and One Paisa");
r |= testC(0.3,"Thirty Paisa");
r |= testC(.3,"Thirty Paisa");
r |= testC(3002900000.50,"Three Hundred Crore, Twenty-Nine Lakh Rupees and Fifty Paisa");
r |= testC(220000,"Two Lakh Twenty Thousand Rupees");
if (r==0) console.log("Test Case 3 Currency (Common-Use Numbering System) Passed.");
//===================================================================
// 4. Test Currency under Official Numbering System
//===================================================================
var r=0; // test tracker
r |= testC(3002900000.50,"Three Arab Twenty-Nine Lakh Rupees and Fifty Paisa",true);
r |= testC(55000000000,"Fifty-Five Arab Rupees",true);
if (r==0) console.log("Test Case 4 Currency (Official Numbering System) Passed.");
//===================================================================
function testN(n,tobe,f) {let r = integerToWordsInd(n,f);
if (r !== tobe) {console.log(`${n} Output   : ${r}\n${n} Should be: ${tobe}`);return 1;}}
function testC(n,tobe,f) {let r = numberCurrencyIn(n,f);
if (r !== tobe) {console.log(`${n} Output   : ${r}\n${n} Should be: ${tobe}`);return 1;}}
EN

回答 1

Code Review用户

发布于 2020-08-02 10:07:39

好吧,我得老实说:这个代码太可怕了。你实际上违反了书中的每一条规则。考虑到你在导言中所做的工作,我不得不假设你是故意的。我的一般建议是:将您所做的努力放在代码中,这样您就不需要编写那么多文档了。

我甚至不会讨论格式化问题,因为我必须在这里复制和粘贴完整的样式指南。出去阅读一些现有的风格指南并将它们应用到您的代码中。或者,如果工作量太大,请在编辑器/IDE/build工具中安装和使用代码格式化程序。

如果您想优化代码执行,请为生产代码使用一个小型程序,但不要仅仅使用语法来编写尽可能少的代码/尽可能少的行,例如:

  • 不要使用逗号操作符。完全没有。尤其是在return表达式中,不像您这样。为什么不直接把map放在return前面呢?(顺便说一句,你在这里滥用map。它应该是forEachreduce )。)
  • 不要误用解构分配,只是为了将尽可能多的代码按进一行。
  • 不要使用&&代替if
  • 不要重用变量,例如Num参数。

“程序是指人类读取程序,只是偶然地让计算机执行。”--唐纳德·克努斯

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/247363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档