Reputation: 148
I have a Ruby array (don't ask me why it is not hash already, i can't do anything about it):
[{":cost=>100", ":size=>2"}]
What do i need to do to make it the classical Ruby hash with keys and values? What is my best option? Maybe there is some libraries for this kind of operations?
Thanks.
Upvotes: 2
Views: 229
Reputation: 110685
You could use the JSON module to do that. That would arguably be safer than by using eval
.
To see how JSON
could be used, let's do some reverse-engineering. You want to create a hash:
h = { :cost=>100, :size=>2 }
from the string:
str = '[{":cost=>100", ":size=>2"}]'
#=> "[{\":cost=>100\", \":size=>2\"}]"
Let's see how that hash would be encoded as a JSON string:
require 'json'
jstr = JSON.generate(h)
#=> "{\"cost\":100,\"size\":2}"
Once we have jstr
(which is nothing more than a string) we can extract the desired hash:
JSON.parse(jstr)
#=> {"cost"=>100, "size"=>2}
so the task reduces to converting str
to jstr
:
"[{\":cost=>100\", \":size=>2\"}]" => "{\"cost\":100,\"size\":2}"
Perhaps the easiest way is to first pull out the keys and values, which we can do with a regex:
r = /
( # start capture group 1
[a-z] # match a lowercase letter
\w* # match >= 0 word characters
) # close capture group 1
=> # match characters
(-?\d+) # optionally match a minus sign followed by > 0 digits in
# capture group 2
/x # free-spacing regex definition mode
arr = str.scan r
#=> [["cost", "100"], ["size", "2"]]
We can now form jstr
:
jstr = "{#{ arr.map { |k,v| "\"#{k}\":#{v}" }.join(",") }}"
#=> "{\"cost\":100,\"size\":2}"
To confirm,
h = JSON.parse(jstr)
#=> {"cost"=>100, "size"=>2}
Upvotes: 1
Reputation: 521
First we need to clean the string to make it look like a valid array:
my_string = my_string[2..-3]
my_array = eval("[#{my_string}]")
Now you can join the strings, and then eval it into a hash:
elements = my_array.join(', ')
my_hash = eval("{ #{ elements } }")
(this can be done in fewer lines, but I separated them for clarity)
Upvotes: 1