Constructing a Hash from a String?

G

Geoff

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 }
 
M

mojombo

Geoff said:
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
 
R

Ross Bamford

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

rcoder

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?
 

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,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top