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 might want to try it recursive. It works for numbers between 0 and 999999. Keep in mind that (~~) does the same as Math.floor
I spent a while developing a better solution to this. It can handle very big numbers but once they get over 16 digits you have pass the number in as a string. Something about the limit of JavaScript numbers.
This is in response to @LordZardeck's comment to @naomik's excellent answer above. Sorry, I would've commented directly but I've never posted before so I don't have the privilege to do so, so I am posting here instead.
Anyhow, I just happened to translate the ES5 version to a more readable form this past weekend so I'm sharing it here. This should be faithful to the original (including the recent edit) and I hope the naming is clear and accurate.
This is also in response to naomik's excellent post! Unfortunately I don't have the rep to post in the correct place but I leave this here in case it can help anyone.
If you need British English written form you need to make some adaptions to the code. British English differs from the American in a couple of ways. Basically you need to insert the word 'and' in two specific places.
The first situation can be addressed by checking for 10s and 1s in the makeGroup method and appending 'and' when they exist.
};
The second case is more complicated. It is equivalent to
1,100,057 one million one hundred thousand and fifty seven. 5,000,006 five million and six
I think this could be implemented in @naomik's code through the use of a filter function but I wasn't able to work out how. In the end I settled on hackily looping through the returned array of words and using indexOf to look for instances where the word 'hundred' was missing from the final element.
Another conversion that uses remainders and supports different languages:
The
getNumberName
function is language-dependent and handles numbers up to 9999 (but it is easy to extend it to handle larger numbers):handleTeensAndTys
handles multiples of ten:Finally, locale examples:
Here's a JSFiddle with tests: https://jsfiddle.net/rcrxna7v/15/
Below are the translations from
Test cases are at the bottom