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

Discussion in 'Ruby' started by Daniel Firu, Jan 16, 2009.

  1. Daniel Firu

    Daniel Firu Guest

    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.
    Daniel Firu, Jan 16, 2009
    #1
    1. Advertising

  2. Daniel Firu

    Daniel Firu Guest

    Re: Convert String to Float if and only if the content of the stringare digits

    On Jan 16, 3:03 pm, Daniel Firu <> wrote:
    > 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.
    Daniel Firu, Jan 16, 2009
    #2
    1. Advertising

  3. Re: Convert String to Float if and only if the content of the string are digits

    On Sat, Jan 17, 2009 at 12:28 AM, Daniel Firu <> wrote:
    > On Jan 16, 3:03 pm, Daniel Firu <> 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.
    Jesús Gabriel y Galán, Jan 17, 2009
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page