Formatted measurement (String to numerical) ???

Recommended Posts

I have a text string ---- 5 1/4"

I need to convert that to a numerical value using Ruby. ie: 5.25

Any ideas?

• 1
Share on other sites

Quite a few ways Joe, here's what I would do though:

1. Remove the inch notation
2. Break into an array of whole numbers and fractions
3. Convert those whole numbers and fractions to rationals as Eric suggested
4. Convert those rationals to floats

If the string could potentially have foot values as well I would probably start by splitting into an array of 2 values using the foot notation as the pattern, multiplying that value by 12 and then adding that to the results obtained from the other half of that array (using the steps mentioned above).

Does that help?

Share on other sites

Thanks guys.  Exactly what I needed.

-Michael, I didn't need to remove the inch notation and I just split the string using the "-" as the separator.

I did it all in a single line of code.

Share on other sites

33 minutes ago, Joe_Carrick said:

I didn't need to remove the inch notation

You are correct.  My bad.  The rationalize method does that automatically (removes or ignores non-numeric characters).  Never realized that before. I guess it makes sense.  Most of the other numeric methods do that as well.

Share on other sites

You are correct.  My bad.  The rationalize method does that automatically.  Never realized that before.

I think it only returns a value up to the 1st non-numeric character.

Share on other sites

4 minutes ago, Joe_Carrick said:

I think it only returns a value up to the 1st non-numeric character.

Just tested quickly and it seems to remove all trailing non-numeric characters.

Share on other sites

Just tested quickly and it seems to remove all trailing non-numeric characters.

YEP!

Share on other sites

From the documentation:

Returns the result of interpreting leading characters in str as a rational. Leading whitespace and extraneous characters past the end of a valid number are ignored.

Share on other sites

Glad you fellows got everything hashed out.

It's like I can see your lips moving but I can't

hear a word you are saying.

• 1
Share on other sites

5 minutes ago, Rich_Winsor said:

Glad﻿ you fellows got eve﻿rything hashed out.﻿﻿

Not hashed Rich, arrayed.

....

I am so sorry

Share on other sites

FYI: Single line conversion is:

x = "5 3/4"

``x = x.split.map { |r| Rational(r) }.inject(:+).to_f   => 5.75``
Share on other sites

6 hours ago, GerryT said:

FYI: Single line conversion is:

x = "5 3/4"

```
`x = x.split.map { |r| Rational(r) }.inject(:+).to_f   => 5.75````

Magic Code I don't think I'll ever be able to fully understand "code blocks"  the way you do.

Share on other sites

15 hours ago, Joe_Carrick said:

I don't think I'll ever be able to fully understand "code blocks"

Hey Joe,

22 hours ago, GerryT said:

.map { |r| Rational(r) }

...since I'm pretty positive you understand the rest quite well.

If my assumption is correct, I may be able to help as it's something that took me quite some time to fully grasp and I personally couldn't even work without anymore.  If it doesn't help you, maybe someone else can take advantage of the free lesson (note that this is NOT intended as a beginner lesson).

It's a lot simpler than it actually seems on the surface.  First off is the .map function, which is really the key to the whole operation.  In plain English, the .map function essentially tells Ruby that you want to do something to every element in your array.  The brackets ({}) encapsulate the thing you want to do.  The .map function is unique in that it will output the results as a modified array.  Anyway, moving on...

Inside those brackets are some pipes (||); and inside those pipes you are essentially just giving a generic name that represents the generic array element.  I believe this generic name (as I call it) is technically called a block parameter but I could be wrong about that part.  In this particular case, Gerry used the letter r, but it could have been any letter.  Right or wrong, I personally just look at this like I'm assigning a temporary variable name.  In fact, you're not even limited to using a single letter (as you'll see in my example below), but a single letter seems to be the typical approach.

After those pipes (and still inside the brackets) is where you describe what you want to do to each element in your array.  I look at this like I'm just modifying a single variable except that whatever I tell Ruby to do will happen to each and every element in the array.  In this case, Gerry used the Rational method using the block parameter (r) as the argument.  For all intents and purposes, Rational(r) is the same thing as r.to_r and is also the same thing as r.rationalize. Just 3 different approaches.

So, as an example, I want to tell Ruby to take my list of numbers, automatically square them, and return them as a list of equations in this basic format:

6² = 36

Creating the array is something I'm sure you're familiar with.  There are many ways, but here's one:

my_list = [1,2,3,4,5,6]

I'm sure you're also perfectly familiar with how to create a variable and how to modify that variable to get the desired format.  Again, there are many ways, but here's one:

temp = 1

temp.to_s + "² = " + (temp*temp).to_s

> 1² = 1

Let's put it all together now by

2. using the .map function
3. starting the code block ({)
4. assigning your "temporary variable name" inside pipes (|temp|
5. inserting the code you want to execute on each element (temp.to_s + "² = " + (temp*temp).to_s)
6. adding a carriage return so that the new list is generated as multi-line text (+ "\n")
7. ending the code block (}) which will essentially result in a new array with appropriately modified elements
8. joining each element in that new array back together as a single text string (.join)
9. and removing the extra carriage return at the end (.strip)

my_list.map{|temp| temp.to_s + "² = " + (temp*temp).to_s + "\n"}.join.strip

>1² = 1

2² = 4

3² = 9

4² = 16

5² = 25

6² = 36

• 1