Reputation: 8976
I need to convert values and keys of a hash to string, in order to correctly prepare it as params for a Net::HTTP.post_form
. For instance:
I need to convert
{:x => [1,2,3,4]}
to
{"x"=>"[1, 2, 3, 4]"}
It's important to convert symbols to string and that arrays are surrounded by quotes.
to_json
returns a string and doesn't solve my problem; I need a hash as return.to_s
to each key or value.How can I perform it?
Upvotes: 1
Views: 9467
Reputation: 8507
What about this
Hash[ { :x => [1,2,3,4] }.map { |k, v| [k.to_s, v.to_s] } ]
#=> {"x"=>"[1, 2, 3, 4]"}
Or on Ruby >= 2.1
{ :x => [1,2,3,4] }.map { |k, v| [k.to_s, v.to_s] }.to_h
#=> {"x"=>"[1, 2, 3, 4]"}
Or on Ruby >= 2.6
{ :x => [1,2,3,4] }.to_h { |k, v| [k.to_s, v.to_s] }
#=> {"x"=>"[1, 2, 3, 4]"}
Upvotes: 11
Reputation: 160553
Don't reinvent a well established wheel. Instead Ruby's URI is a good tool to use:
require 'uri'
uri = URI.parse('http://www.example.com')
uri.query = URI.encode_www_form( {:x => [1,2,3,4]} )
uri.to_s # => "http://www.example.com?x=1&x=2&x=3&x=4"
If you want just the query values:
query = URI.encode_www_form( {:x => [1,2,3,4]} ) # => "x=1&x=2&x=3&x=4"
It really sounds like you are reinventing wheels if you are going to send that through Net::HTTP. Serializing a hash to {"x"=>"[1, 2, 3, 4]"}
will limit your code to working with only your code. Using JSON, YAML or XML would make your life easier and your code more portable.
JSON makes it easy to move a hash from machine to machine, between languages like Ruby/Python/Java/Perl, whether it is a browser to a server, or client to server:
require 'json'
hash = {:x => [1,2,3,4]}
hash.to_json
=> "{\"x\":[1,2,3,4]}"
JSON[hash.to_json]
=> {
"x" => [
[0] 1,
[1] 2,
[2] 3,
[3] 4
]
}
That's a round-trip of the hash, to JSON's representation, back to the hash. The intermediate string "{\"x\":[1,2,3,4]}"
is easily sent via Net::HTTP.
Upvotes: 4