Parse Integer from a String of Written Numbers ?
This may seem like a very tall order to some, but if we just take things one step at a time anything can be accomplished. If you are ready to get started, you can download a copy of the repo here that includes a variety of different tests to help us check our progress. Otherwise let’s jump right into it.
The first question, and probably the biggest, that we should be asking ourselves right off the bat is, how will a written number translate to an actual number? Well, we will have to make a library of sorts that stores a record of all our distinct written numbers and their numerical value. Sound a little familiar? We can use an object to store such a library, with keys being written numbers and values being the actual number. I also mentioned distinct values, by this I mean unique. For example, zero to twenty are all very distinctly written. From twenty onwards to ninety, we will move by tens like thirty, forty, fifty, etc. We would not have to create a key value for twenty-five as we have already done so separately for twenty and five.
For this example, we will be creating two objects, the first for small numbers and second for big numbers. Our small numbers object will contain distinct key value pairs from 0 to 99. Our big numbers object will hold our distinct values from a hundred to a billion, although feel free to add higher number denominations should you please. Take a look at the example below to help get a better understanding of our little ‘library’.
As you can see, we have recorded key values for every distinct or unique numerical value we could be faced with. Again, should we face numbers that we have not created key values for, we will be able to use a combination of two key values to get our number. You will also notice that it has been placed just above our function, and that is where it will stay. Now that we and our function have all the information needed to start coding, let’s get right to it!
Now that we are finally into the function, we know that we are going to be handed a string that contains the written value of the number. We know that our string can contain non-numerical words most commonly and, but we also know that some letter can be separated by a dash (-). We are not so much worried with the latter but do need to worry about any and all dashes we may encounter. This is because after we do this, we will be breaking up our string into an array. Before I get too ahead of myself take a look at the example below, both the lines of code do the same exact thing. This will depend on your version of node/browser.
In both cases we are replacing our dashes with empty spaces, so to break up words like thirty-five or seventy-eight. That way we can process the numbers more easily and you will see soon. For the remainder of this exercise, we will be sticking with the split and join method as replace all is somewhat still relatively new. But will keep it commented out for reference. Plus, we now get to learn what is actually happening when we split and join together, although we will be splitting it again very soon.
If we split a string, we are essentially splitting our string into different parts of an array. By specifying a dash as our breaking point, every time split comes across a dash, it will create a new index in the array and deleting the dash as well. Should we split ‘twenty-four’ we would be left with [‘twenty’, ‘four’]. This would be great if all our given numbers would be under ninety-nine. But what if we had one hundred twenty-four. We could be returned with [ ‘one hundred twenty’, ‘four’]. Not exactly what were looking for as we are left with three values under one index. By joining our array back into one string divided by a space, we would then be returned with ‘one hundred twenty four’. Now that looks like something we can work with.
If you couldn’t have guessed by now, we are going to need to loop through each numerical part of our string and to do so we will be splitting our string at every space. As a precaution since you never know how someone else will input their information, we will make our string lower case before splitting it up. Take a look at the example below.
Now that we have an array of each word that is most likely a value that needs to be processed, we can start by creating a for loop. This loop will simply give us access to each of our array’s values one by one.
Now that we have access to individual values continuously, we are faced with one small issue. We have two different number objects and our current value from the array could be in either of them. Well not to worry, we simply need to create two conditional if statements. And this is where the magic of using objects with key values comes into play. Take a look at the two conditionals that have been added to our loop.
Two things are going on here that I want to explain to you. One, if you remember if statements, should the condition be true then we enter into that if statement. On the other hand, should our condition be false we will skip right over it. Depending on the value of the index from our string array, it may or may not be in one or the other, or any at all.
What’s really important though is what our condition actually is doing. By using our written word as a key to either our small or large numbers objects, we are checking to see if that key has a value. This will return the key which would be a number should it exist or return undefined should it not exist. In the context of our if statements, this helps us to know which object we need to pull from. Not to mention at this point, should we get a word that is not a number such as and. Our function will simply skip over it as it is not included in either of the objects we are pulling from.
Since our small numbers conditional is up first let’s tackle that one first, it also turns out to be the easier of the two. This is because we have split up all our smaller numbers or numbers under a hundred, we simply need to add that number to our number total. Now that we are up to this point, we can add a variable of num equal to zero just before our loop statement. This will represent our total number, and since we haven’t started looping our array of numbers, it should be set to zero. This can be achieved like so.
This will now add all numbers smaller than one hundred to our total of numbers. This should be all we need to complete, right? Well, what if you were to get a number that was larger than ninety-nine, say ninety thousand or seventeen billion? Since we have already added ninety or seventeen to our number total how will our function know that its seventeen thousand and a thousand seventeen? To overcome this obstacle, we will create another new variable just under our number total variable. We will call this variable last num as it is the last number to have been added to our number total. If we slide back into our small number conditional, after adding our current number we will simply make last num that number.
We have now completed our small numbers conditional and will now be tackling our big numbers conditional to finish out our function. This may seem somewhat straight forward in what we need to do, which will be somewhat like our small number conditional. Take for example we are given the number six hundred or nine thousand. Both six and nine are already in our number total, we can simply multiply our number total to achieve both ends. Take a look at the example below.
This poses an issue to us though, while this will work for the numbers I have listed before as well as others. But what if we were given a number like five thousand two hundred and fifty, do you still think it will work out in our favor? Unfortunately, it will not, we will be returned with five hundred thousand two hundred and fifty. This is because after three is added to two thousand, instead of making that two, two hundred. We are actually multiplying five thousand and three time a hundred, thus leading us to five hundred thousand two hundred.
The reason for this being is we don’t have denominations in thousands of hundreds, it’s quite the opposite. This is where we will need to create another conditional statement, where our condition will be if our number is less than a thousand. The reason for this being because we want to add our smaller big denominations afterwards to avoid the mishap we would be presented with before. The reason the number is less than a thousand is because anything up to nine hundred and ninety-nine can be part of a thousand, million, or billion for our largest denomination. Let’s take a look at how we can initially set up our new conditional. Since I am already inside of an if statement let’s use some ternary conditionals.
As you can see, we have done just that, should our current total be less then a thousand then we will multiply that number by our total. Should it not though, nothing will currently happen although we still need something to happen. Let’s recall our last example of five thousand two hundred and fifty, how are we going to add three and then make that three hundred without interfering with our current total? Well, this is where our last num variable is going to help us our big time.
Our small number conditional is already taking care of adding the three to our total so that is something we won’t need to worry about but transforming that three into three hundred is something else completely. Well, we won’t actually be transforming that three but bear with me. We know that our last number was three thanks to our handy variable and that our current number is a hundred. Let’s multiply the two and then add it to our current total. This still leaves us with one small issue though, our total still has a two in the ones place which would give us five thousand two hundred and two.
To overcome this small hurdle, we will simply subtract our last number after our last number has been multiplied by the current value. Instead of adding two hundred, we will really be adding the difference needed to equal the number we are looking for. Take a look below at the finished ternary conditional.
There are still two small issues we need to address before we are fully finished with our function. The first being what if we were given the number one hundred million one hundred thousand. Since we have stored our hundred value within our big numbers object we will run into an issue when a hundred thousand tries to be implemented. This is because when it looks to see the last number it will see one instead of one hundred.
To easily avoid this, we will simply need to make our last number added our current number multiplied by our last number. This differs slightly from our last conditional in that we are not looking for the difference that was added, we simply want the whole number as that is what will be taken our in the next step once it has gone through our ternary conditional. Our last and final step is to return our total number after our loop has finished interpreting our given string. Take a look below at the completed function.
Congratulations everyone we have built our new parse integer function that converts a string of words into a number! I would like to thank you for reading along and hope that you have learned something new! Keep an eye out for more articles and walkthroughs in the future!
If you would like to view a copy of these examples to play around with for yourself or just for reference, you can find the link for the GitHub Repo here.