# Convert String to Float if and only if the content of the string are digits

**URL:** <https://www.ruby-forum.com/t/convert-string-to-float-if-and-only-if-the-content-of-the-string-are-digits/157962>\
**Category:** Ruby\
**Created:** [January 17, 2009, 12:05am UTC](https://www.ruby-forum.com/t/convert-string-to-float-if-and-only-if-the-content-of-the-string-are-digits/157962 "2009-01-17T00:05:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![arachnd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@arachnd](https://www.ruby-forum.com/u/arachnd)\
**Post date:** [January 17, 2009, 12:05am UTC](https://www.ruby-forum.com/t/convert-string-to-float-if-and-only-if-the-content-of-the-string-are-digits/157962/1 "2009-01-17T00:05:48Z")

</div>

Hi All,

Long time reader – first time poster. Basically, I have a bunch of  
data that is sucked in from a file. From reading the pick axe book,  
it is my understanding that this data by default will be a string even  
if the contents of that string are a bunch of digits. Well, in the  
case that a string is solely composed of digits, I want to convert  
them to a float for the purpose of using the \<=\> operator. I’ll just  
go ahead and throw in my method and let you guys tear it a part. The  
goal of the function is to soft my array of arrays based on a  
particular element defined by a ‘key’. Maybe there is an easier way  
to do this all together.

def sort(_keys) options = {}  
regex = "^(\d)_$"  
newData = Array.new  
keys.reverse!  
keys.each do |key|  
newData = @data  
keyIndex = @header.index(key)  
newData.sort! do |entry1, entry2|  
if (!(entry1[keyIndex].match(regex).nil? && entry2  
[keyIndex].match(regex).nil?))  
print “I found only digits\n”  
entry1[keyIndex].to\_f \<=\> entry2[keyIndex].to\_f  
else  
#print “I found something other than digits\n”  
entry1[keyIndex] \<=\> entry2[keyIndex]  
end  
end  
end  
newTable = Table.new({  
:header =\> @header,  
:data =\> newData  
})  
newTable  
end

Thanks in advance for you feedback. Feel free to be brutal – I have  
thick skin and am still learning.

---

<div class="post-metadata">

**Author:** ![arachnd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@arachnd](https://www.ruby-forum.com/u/arachnd)\
**Post date:** [January 17, 2009, 4:35pm UTC](https://www.ruby-forum.com/t/convert-string-to-float-if-and-only-if-the-content-of-the-string-are-digits/157962/2 "2009-01-17T16:35:26Z")

</div>

On Sat, Jan 17, 2009 at 12:28 AM, Daniel F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> On Jan 16, 3:03 pm, Daniel F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

First of all I would like to ask you some questions about the design  
of classes and objects you have.  
It seems that this is an instance method of a class, cause you are  
using a couple of instance variables  
(@data and @header). In this method, though, you are modifying @data,  
cause you are doing a sort! on it.  
Don’t know if this side effect is on purpose or not, and if it has  
some benefits or problems. It’s also not clear to me why you sort the  
data in a loop, each time with a different key. Maybe what you want is  
to sort based on a set of keys. Your algorithm (sorting by the last  
key, then sorting the result by the second to last, etc) might not  
yield the same results as sorting based on all keys at the same time.  
Maybe you want this (untested):

def sort(\*keys, options = {})

# BTW, what is options? You never use it in your code, and the fact

that is outside of the parenthesis, but in the same line makes me

# wonder if you wanted that or what I just wrote

indexes = keys.map {|k| @head.index(k)}  
sorted = @data.sort do |entry1, entry2|  
first, second = process\_values(entry1.values\_at(indexes),  
entry2.values\_at(indexes))  
first \<=\> second  
end  
Table.new({:header =\> @header, :data =\> sorted})  
end

# Convert matching pairs of each array with to\_f if both contain only

digits  
def process\_values(first, second)  
regex = /\A(\d\*)\z/  
first.zip(second).inject([[],[]]) do |(f,s), (v1,v2)|  
if (v1 =~ regex && v2 =~ regex)  
puts “Only digits found”  
v1 = v1.to\_f  
v2 = v2.to\_f  
end  
[f \<\< v1, s \<\< v2]  
end  
end

This version is sorting based on an array that contains the value for  
each key.  
Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![arachnd](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/278dde/32.png) [@arachnd](https://www.ruby-forum.com/u/arachnd)\
**Post date:** [January 17, 2009, 12:31am UTC](https://www.ruby-forum.com/t/convert-string-to-float-if-and-only-if-the-content-of-the-string-are-digits/157962/3 "2009-01-17T00:31:00Z")

</div>

On Jan 16, 3:03 pm, Daniel F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> particular element defined by a ‘key’. Maybe there is an easier way  
> if (!(entry1[keyIndex].match(regex).nil? && entry2  
> :header =\> @header,  
> :data =\> newData  
> })  
> newTable  
> end
> 
> Thanks in advance for you feedback. Feel free to be brutal – I have  
> thick skin and am still learning.

Hi All,

I went ahead and changed my method to:

def sort(\*keys) options = {}  
regex = Regexp.new(‘^\d+$’)  
newData = Array.new  
keys.reverse!  
keys.each do |key|  
newData = @data  
keyIndex = @header.index(key)  
newData.sort! do |entry1, entry2|  
if (entry1[keyIndex] =~ regex && entry2[keyIndex] =~ regex)  
#print “I found only digits\n”  
entry1[keyIndex].to\_f \<=\> entry2[keyIndex].to\_f  
else  
#print “I found something other than digits\n”  
entry1[keyIndex] \<=\> entry2[keyIndex]  
end  
end  
end  
newTable = Table.new({  
:header =\> @header,  
:data =\> newData  
})  
newTable  
end

Now the question still remains if there is a better way to do this  
sorting.
