这对于普通哈希来说很简单
{: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"}]
非常感谢你的帮助!
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
我知道这是一个老问题,但我只是想张贴这段代码,因为我找不到一个简单的宝石来为我做这个任务。
module QueryParams
def self.encode(value, key = nil)
case value
when Hash then value.map { |k,v| encode(v, append_key(key,k)) }.join('&')
when Array then value.map { |v| encode(v, "#{key}[]") }.join('&')
when nil then ''
else
"#{key}=#{CGI.escape(value.to_s)}"
end
end
private
def self.append_key(root_key, key)
root_key.nil? ? key : "#{root_key}[#{key.to_s}]"
end
end
在这里汇总为宝石:https://github.com/simen/queryparams
2.6.3 :001 > hash = {:a => "a", :b => ["c", "d", "e"]}
=> {:a=>"a", :b=>["c", "d", "e"]}
2.6.3 :002 > hash.to_a.map { |x| "#{x[0]}=#{x[1].class == Array ? x[1].join(",") : x[1]}"
}.join("&")
=> "a=a&b=c,d,e"
对于基本的、非嵌套的散列,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