Constructing a Hash from a String?

Discussion in 'Ruby' started by Geoff, May 12, 2006.

  1. Geoff

    Geoff Guest

    So I'm looking to create a Hash from a string which is pretty much
    formatted like you would create a hash:

    theString = "foo=>1,bar=>2,baz=>'go fish'"

    and i was wondering if anyone had any nice and simple ideas for how to
    grab this out. I came up with a little way to do it but i was just
    wondering if anyone out there can think of a shorter way.

    Here's what i came up with:

    login = Hash.new
    theString.split(',').each {|pair| pair.match(/(.+)=>(.+)/);
    login[$1.intern]=$2 }
     
    Geoff, May 12, 2006
    #1
    1. Advertising

  2. Geoff

    Guest

    Geoff wrote:
    > So I'm looking to create a Hash from a string which is pretty much
    > formatted like you would create a hash:
    >
    > theString = "foo=>1,bar=>2,baz=>'go fish'"
    >
    > and i was wondering if anyone had any nice and simple ideas for how to
    > grab this out. I came up with a little way to do it but i was just
    > wondering if anyone out there can think of a shorter way.


    This is a bit obfuscational, but it works:

    login = eval('{' + theString.split(',').map{|m| ':' + m}.join(',') +
    '}')

    Tom
     
    , May 12, 2006
    #2
    1. Advertising

  3. Geoff

    Ross Bamford Guest

    On Fri, 12 May 2006 18:43:45 +0100, Geoff <> wrote:

    > So I'm looking to create a Hash from a string which is pretty much
    > formatted like you would create a hash:
    >
    > theString = "foo=>1,bar=>2,baz=>'go fish'"
    >
    > and i was wondering if anyone had any nice and simple ideas for how to
    > grab this out. I came up with a little way to do it but i was just
    > wondering if anyone out there can think of a shorter way.
    >
    > Here's what i came up with:
    >
    > login = Hash.new
    > theString.split(',').each {|pair| pair.match(/(.+)=>(.+)/);
    > login[$1.intern]=$2 }
    >


    Depends on exactly how you want the Hash, but maybe you could do:

    h = Hash[*the_string.split(',').map { |e| e.split('=>') }.flatten]
    # => {"baz"=>"'go fish'", "foo"=>"1", "bar"=>"2"}

    or:

    h = Hash[*the_string.split(',').map do |e|
    e.split('=>').inject { |k,v| [k.intern,eval(v)] }
    end.flatten]
    # => {:foo=>1, :bar=>2, :baz=>"go fish"}

    Unfortunately, if you want the second style I think you're stuck with eval
    and it's (deserved) reputation as slow and insecure.

    --
    Ross Bamford -
     
    Ross Bamford, May 12, 2006
    #3
  4. Geoff

    rcoder Guest

    I'd recommend staying away from using the Ruby hash syntax, unless you
    also want to implement a parser for Ruby strings -- your simple version
    will break if any values in your hash include a comma. For example:

    theString = "foo=>1,bar=>2,baz=>'go fish, then go home'"

    Your split will find the comma in the value associated with baz, but
    the search for '=>' will fail, resulting in a truncated value for the
    baz key.

    Have you considered using YAML, or another non-Ruby syntax for the
    hashes?
     
    rcoder, May 12, 2006
    #4
  5. Geoff

    Geoff Guest

    YAML could be an option. I'll look in to it.

    Thanks for the suggestions.
     
    Geoff, May 15, 2006
    #5
    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.
Similar Threads
  1. Todd Bandrowsky

    Constructing a Class Given a String

    Todd Bandrowsky, May 21, 2004, in forum: C++
    Replies:
    1
    Views:
    356
    Victor Bazarov
    May 21, 2004
  2. rp
    Replies:
    1
    Views:
    556
    red floyd
    Nov 10, 2011
  3. Chris McMahon

    Help constructing interesting hash?

    Chris McMahon, Nov 30, 2005, in forum: Ruby
    Replies:
    9
    Views:
    122
    Simon Strandgaard
    Dec 1, 2005
  4. Tim L
    Replies:
    1
    Views:
    100
    Robert Klemme
    Apr 12, 2006
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    640
    David A. Black
    Jul 2, 2008
Loading...

Share This Page