I am making a code which converts the given amount into words, heres is what I have got after googling. But I think its a little lengthy code to achieve a simple task.
Two Regular Expressions and two for
loops, I want something simpler.
I am trying to make it as shorter as possible. and will post what I come up with
Any suggestions?
var th = ['','thousand','million', 'billion','trillion'];
var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function toWords(s) {
s = s.toString();
s = s.replace(/[\, ]/g,'');
if (s != parseFloat(s)) return 'not a number';
var x = s.indexOf('.');
if (x == -1)
x = s.length;
if (x > 15)
return 'too big';
var n = s.split('');
var str = '';
var sk = 0;
for (var i=0; i < x; i++) {
if ((x-i)%3==2) {
if (n[i] == '1') {
str += tn[Number(n[i+1])] + ' ';
i++;
sk=1;
} else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';
sk=1;
}
} else if (n[i]!=0) { // 0235
str += dg[n[i]] +' ';
if ((x-i)%3==0) str += 'hundred ';
sk=1;
}
if ((x-i)%3==1) {
if (sk)
str += th[(x-i-1)/3] + ' ';
sk=0;
}
}
if (x != s.length) {
var y = s.length;
str += 'point ';
for (var i=x+1; i<y; i++)
str += dg[n[i]] +' ';
}
return str.replace(/\s+/g,' ');
}
Also, the above code converts to English numbering system like Million/Billion, I wan't South Asian numbering system. like in Lakhs and Crores
You can check my version from github. It is not so hard way. I test this for the numbers between 0 and 9999, but you can extend array if you would like digits to words
Indeed. There's many little devils hanging out in the details of this problem. It was very fun to solve tho.
EDIT: This update takes a much more compositional approach. Previously there was one big function which wrapped a couple other proprietary functions. Instead, this time we define generic reusable functions which could be used for many varieties of tasks. More about those after we take a look at
numToWords
itself …Here are the dependencies:
You'll notice these require next to no documentation because their intents are immediately clear.
chunk
might be the only one that takes a moment to digest, but it's really not too bad. Plus the function name gives us a pretty good indication what it does, and it's probably a function we've encountered before."So these make it better?"
Look at how the code has cleaned up significantly
Most importantly, the utility functions we added in the new code can be used other places in your app. This means that, as a side effect of implementing
numToWords
in this way, we get the other functions for free. Bonus soda !Some tests
Runnable demo
You can transpile the code using babel.js if you want to see the ES5 variant
This is modified code supports for Indian Rupee with 2 decimal place.
Though, this question has been answered - still I want to share something I recently developed in java script (based on the logic of an old C#. Net implementation I found in Internet) for converting Indian currency values to Words. It can handle up to 40 digits. You can have a look.
Usage: InrToWordConverter.Initialize();. var inWords = InrToWordConverter.ConvertToWord(amount);
Implementation:
Here's a shorter code. with one RegEx and no loops. converts as you wanted, in south asian numbering system
The only limitation is, you can convert maximum of 9 digits, which I think is more than sufficient in most cases..
Update: Looks like this is more useful than I thought. I've just published this on npm. https://www.npmjs.com/package/num-words
I've just written paisa.js to do this, and it handles lakhs and crores correctly as well, can check it out. The core looks a bit like this: