Convert String to Float if and only if the content of the string aredigits

D

Daniel Firu

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.
 
D

Daniel Firu

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.

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.
 
J

Jesús Gabriel y Galán

On Jan 16, 3:03 pm, Daniel Firu <[email protected]> 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top