0

I have a record of class String something like:

"{'1'=>'abc', '2'=> 'def'}"

but from this i need this in class Hash, something like:

{'1'=>'abc', '2'=> 'def'}

how to convert like this?

Edit: in my case i was getting this from CSV from other service where they were converting Hash into String before sending, so i asked them to send it using Base64.encode64 and now i am able to decode and get it in Hash format.

  • 3
    this can help you https://stackoverflow.com/questions/1667630/how-do-i-convert-a-string-object-into-a-hash-object – Rokas Rudys Jul 26 '22 at 14:25
  • 2
    Why do you have an `inspect`'ed Ruby Hash as a String in the first place? Instead of trying to parse the string, you should instead try to retain the original Hash object, rather than converting it to a String and than later parsing it again. – Holger Just Jul 26 '22 at 18:41
  • @HolgerJust thats how i am getting it from CSV file and i need to process further that `Hash` that's present in that string. – Ramachandra Hegde Jul 27 '22 at 07:09

3 Answers3

2

If you trust that the data is not nefarious you can write

str = "{'1'=>'abc', '2'=> 'def'}"

h = eval str
  #=> {"1"=>"abc", "2"=>"def"}

See Kernel#eval.

If the data could be nefarious it would be safer to write

str.gsub(/{ *| *\|'/, '')
   .split(/ *, */)
   .map { |s| s.split(/ *=> */) }
   .to_h
  #=>  {"1"=>"abc", "2"=>"def"}
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
1

This answer might not related to the question that i asked, but this is what solved my case, since other service was sending few Hash records in CSV format, they were converting the Hash to String before posting it to me. So i asked them to use Base64.encode64 and send the encoded string in CSV.

Base64.encode64({'1'=>'abc', '2'=> 'def'}.to_json).delete("\n")
  #=> "eyIxIjoiYWJjIiwiMiI6ImRlZiJ9"

and when i get the string i am converting it back to Hash something like

JSON.parse(Base64.decode64("eyIxIjoiYWJjIiwiMiI6ImRlZiJ9"))
  #=> {"1"=>"abc", "2"=>"def"}
  • 1
    Ah, haven't read this before commenting. Yes, standard formats are the answer; making sense of bad data formats is a last-resort fallback when you can't fix the format to something standard. You don't need Base64, JSON can go into CSV perfectly fine if it is correctly escaped (i.e. each double quote `"` replaced by a double double quote `""`), as any CSV library would do. (Just beware homebrewed "CSV" — seemingly simple format, but many people mess it up) – Amadan Jul 27 '22 at 07:26
0

If I were writing a parser for objects that were in Ruby's object notation, not Javascript's, I'd call it either RON or RSON. I like the pun in the second better, so I think I'd go with RSON.

A quick google confirms that at least one other person thinks like I do, or at least arrives at the same conclusion: https://github.com/tannevaled/rson. So one option would be to use the rson gem, if it still works.

Alternatively, if you're not expecting any quotes or => to appear in any of the strings, you'd probably get away with something like

h = JSON.parse(str.gsub(/\s*=>\s*/, ":").gsub("'", '"'))
Simon
  • 25,468
  • 44
  • 152
  • 266