Bob
Bob

Reputation: 121

Missing space in javascript numbers to words converter

I've created a numbers to words converter for 0-999 and have almost got it working perfectly apart from one bug.

In certain numbers over a hundred there is a space missing between the 'hundred' section and the 'tens/units' section.

For example 864 gives 'eth canspajar ha tri ugens' where there needs to be a space between the cans and the pajar (hundred = cans)

It seems to be a regular problem because it happens to 164, 264, 364, etc, and ranges of other numbers.

Can anyone with a better knowledge of Javascript or maths take a look at my code and see if they can spot the pattern, or a solution? The code is taken from a French number converter which I didn't make and I'm relatively new to Javascript so it's tricky for me to completely understand everything that's there.

You can see the code below or at http://jsfiddle.net/nickykw/tMXmj/2/

Many thanks

function num2Letters(number) {

  if (isNaN(number) || number < 0 || 999 < number) {
    return '';//'Veuillez entrer un nombre entier compris entre 0 et 999.';
  }

  var units2Letters = ['', 'onen', 'dew', 'tri', 'pajar', 'pemp', 'whegh', 'seyth', 'eth', 'naw', 'deg', 'udnek', 'dowdhek', 'tredhek', 'peswardhek', 'pemthek', 'whetek', 'seytek', 'etek', 'nownsek'],
    tens2Letters = ['', 'deg', 'ugens', 'warn ugens', 'dew ugens', 'ha dew ugens', 'tri ugens', 'ha tri ugens', 'pajar ugens', 'ha pajar ugens'];
  twenties2Letters = ['', 'deg', 'ugens', 'warn ugens', 'dew ugens', 'ha dew ugens', 'tri ugens', 'ha tri ugens', 'pajar ugens', 'ha pajar ugens', 'pemp ugens', 'ha pemp ugens', 'whegh ugens', 'ha whegh ugens', 'seyth ugens', 'ha seyth ugens', 'eth ugens', 'hag eth ugens', 'naw ugens', 'ha naw ugens'];
  hundreds2Letters = ['', 'cans', 'dew cans', 'tri hans', 'pajar cans', 'pemp cans', 'whegh cans', 'seyth cans', 'eth cans', 'naw cans'];

  var units = number % 10,
    tens = (number % 100 - units) / 10,
    twenties = (number % 200 - units) / 10,
    hundreds = (number % 1000 - number % 100) / 100;

  var unitsOut, tensOut, twentiesOut, hundredsOut;

  if (number === 0) {
    return 'mann';
  } else {
    // THE UNITS
    unitsOut = units2Letters[units];
    // THE TENS
    if (tens === 1 && units > 0) {
      tensOut = units2Letters[10 + units];
      unitsOut = '';
    } else if (tens === 2 && units !== 0) {
      tensOut = units2Letters[units] + ' warn ' + tens2Letters[tens];
      unitsOut = '';
    } else if (tens === 3) {
      tensOut = units2Letters[10 + units] + ' ' + tens2Letters[tens];
      unitsOut = '';
    } else if ((tens === 4 && units !== 0) || (tens === 6 && units !== 0) || (tens === 8 && units !== 0)) {
      tensOut = units2Letters[units] + ' ha ' + tens2Letters[tens];
      unitsOut = '';
    } else if (tens === 5 || tens === 7 || tens === 9) {
      tensOut = units2Letters[10 + units] + ' ' + tens2Letters[tens];
      unitsOut = '';
    } else {
      tensOut = tens2Letters[tens];
    }

    // THE TWENTIES - used only for 120-199
    if ((number >= 121 && number <= 199) && (tens === 2 || tens === 4 || tens === 8) && units > 0) {
      twentiesOut = units2Letters[units] + ' ha ' + twenties2Letters[twenties];
    } else if ((number >= 121 && number <= 199) && (tens === 3 || tens === 5 || tens === 7 || tens === 9)) {
      twentiesOut = units2Letters[10 + units] + ' ' + twenties2Letters[twenties];
    } else if ((number >= 121 && number <= 199) && (tens === 6)) {
      twentiesOut = units2Letters[units] + ' hag ' + twenties2Letters[twenties];
    } else {
      twentiesOut = twenties2Letters[twenties];
    }
    // THE HUNDREDS

    //if the number is x01-09 or number is x1x or number is x2x or number is x3x then add a hag/ha after the number (hag if the number is xx1 or xx8 or x20)
    if ((hundreds >= 1 && tens === 0 && units >= 1) || hundreds >= 1 && tens === 1 || hundreds >= 1 && tens === 2 || hundreds >= 1 && tens === 3) {
      hundredsOut = hundreds2Letters[hundreds] + (hundreds >= 1 && (units === 1 || units === 8) || hundreds >= 1 && tens === 2 && units === 0 ? ' hag ' : ' ha ');
      // insert a ha for 40, 60 and 80 above 200
    } else if (hundreds >= 2 && (tens === 4 || tens === 6 || tens === 8) && units === 0) {
      hundredsOut = hundreds2Letters[hundreds] + ' ha ';
    } else {
      hundredsOut = hundreds2Letters[hundreds];
    }

    // GET TOTAL
    if (number === 50) {
      return hundredsOut + (hundredsOut && tensOut ? ' ' : '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut + ' <i>or</i> hanter cans';
    } else if (number === 150) {
      return hundredsOut + (hundredsOut && tensOut ? ' ' : '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut + ' <i>or</i> deg ha seyth ugens <i>or</i> onen cans ha hanter';
    } else if (hundreds > 1 && tens === 5 && units === 0) {
      return hundredsOut + (hundredsOut && tensOut ? ' ' : '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut + ' <i>or</i> ' + hundredsOut + ' ha hanter';
    } else if (hundreds === 1 && (tens === 2 || tens === 3 || tens === 4 || tens === 5 || tens === 6 || tens === 7 || tens === 8 || tens === 9)) {
      return twentiesOut + ' <i>or</i> ' + hundredsOut + (hundredsOut && tensOut ? '' : '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut;
    } else {
      return hundredsOut + (hundredsOut && tensOut ? '' : '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut;
    }
  }
}
const userEntry = document.getElementById('userEntry');
document.getElementById('userEntry').addEventListener('input', function() { document.getElementById('result').innerHTML = num2Letters(parseInt(this.value, 10))});
Enter a number between 0 and 999: <input id="userEntry" type="text"/>
<span id="result"></span>

Upvotes: 0

Views: 461

Answers (3)

Mark M
Mark M

Reputation: 976

I believe that you have 2 issues here:

  1. In "THE HUNDREDS" section you are concatenating " hag " and " ha " - you need to remove the trailing spaces. As the last item in the concatenation you can't predict at that point whether to append a space at the end or not.
  2. In the "GET TOTAL" section the return should be updated as follows:

return hundredsOut + (hundredsOut && tensOut ? ' ': '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? ' ' : '') + unitsOut;

This is the proper place to insert spaces.

Upvotes: 1

Gavriel
Gavriel

Reputation: 19237

Here you have ? '' : '' which doesn't make sense, I guess one of them needs to be ' ' (space), if not ,then you don't even need the trinary operator, just put there ''

    } else if (hundreds === 1 && (tens === 2 || tens === 3 || tens === 4 || tens === 5 || tens === 6 || tens === 7 || tens === 8 || tens === 9) ) {

        return twentiesOut + ' <i>or</i> ' + hundredsOut + (hundredsOut && tensOut ? '': '') + tensOut + (hundredsOut && unitsOut || tensOut && unitsOut ? '' : '') + unitsOut;

Upvotes: 1

Ray Toal
Ray Toal

Reputation: 88378

Rather that trying to find the missing space, I would suggest that you restructure the code so that you not compose strings on the fly, but rather to add components of your phrase to an array (using push or concat as needed), then call join on the array.

For example

var result = ['eth','cans'];
result.push('pajar');
result = result.concat(['ha','tri','ugens']);
alert(result.join(' '));

The advantage here is that your code is much cleaner and you do not have to worry about trimming leading and trailing spaces that might end up here and there for certain inputs.

Upvotes: 3

Related Questions