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


#1

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.


#2

On Sat, Jan 17, 2009 at 12:28 AM, Daniel F. removed_email_address@domain.invalid
wrote:

On Jan 16, 3:03 pm, Daniel F. 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.


#3

On Jan 16, 3:03 pm, Daniel F. 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.