这对于普通哈希来说很简单
{:a => "a", :b => "b"}
这就意味着
"a=a&b=b"
但是你怎么处理更复杂的东西,比如
{:a => "a", :b => ["c", "d", "e"]}
这应该转化为
"a=a&b[0]=c&b[1]=d&b[2]=e"
或者更糟的是,(该怎么做)像这样的事情:
{:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]
非常感谢你的帮助!
对于基本的、非嵌套的散列,Rails/ActiveSupport有object# to_query。
>> {:a => "a", :b => ["c", "d", "e"]}.to_query
=> "a=a&b%5B%5D=c&b%5B%5D=d&b%5B%5D=e"
>> CGI.unescape({:a => "a", :b => ["c", "d", "e"]}.to_query)
=> "a=a&b[]=c&b[]=d&b[]=e"
http://api.rubyonrails.org/classes/Object.html#method-i-to_query
class Hash
def to_params
params = ''
stack = []
each do |k, v|
if v.is_a?(Hash)
stack << [k,v]
elsif v.is_a?(Array)
stack << [k,Hash.from_array(v)]
else
params << "#{k}=#{v}&"
end
end
stack.each do |parent, hash|
hash.each do |k, v|
if v.is_a?(Hash)
stack << ["#{parent}[#{k}]", v]
else
params << "#{parent}[#{k}]=#{v}&"
end
end
end
params.chop!
params
end
def self.from_array(array = [])
h = Hash.new
array.size.times do |t|
h[t] = array[t]
end
h
end
end
偷Merb的东西:
# File merb/core_ext/hash.rb, line 87
def to_params
params = ''
stack = []
each do |k, v|
if v.is_a?(Hash)
stack << [k,v]
else
params << "#{k}=#{v}&"
end
end
stack.each do |parent, hash|
hash.each do |k, v|
if v.is_a?(Hash)
stack << ["#{parent}[#{k}]", v]
else
params << "#{parent}[#{k}]=#{v}&"
end
end
end
params.chop! # trailing &
params
end
参见http://noobkit.com/show/ruby/gems/development/merb/hash/to_params.html
我喜欢使用这个宝石:
https://rubygems.org/gems/php_http_build_query
示例用法:
puts PHP.http_build_query({"a"=>"b","c"=>"d","e"=>[{"hello"=>"world","bah"=>"black"},{"hello"=>"world","bah"=>"black"}]})
# a=b&c=d&e%5B0%5D%5Bbah%5D=black&e%5B0%5D%5Bhello%5D=world&e%5B1%5D%5Bbah%5D=black&e%5B1%5D%5Bhello%5D=world