有没有办法将哈希压缩成字符串,键和值之间有可选的分隔符,以及键/值对?
例如,print {:a => :b, :c => :d}.flatten('=','&')
应打印a=b&c=d
我写了一些代码来做这件事,但我想知道是否有更简洁的方法:
class Hash
def flatten(keyvaldelimiter, entrydelimiter)
string = ""
self.each do
|key, value|
key = "#{entrydelimiter}#{key}" if string != "" #nasty hack
string += "#{key}#{keyvaldelimiter}#{value}"
end
return string
end
end
print {:a => :b, :c => :d}.flatten('=','&') #=> 'c=d&a=b'
由于
答案 0 :(得分:105)
我不会覆盖已经定义的.flatten
:
返回一个新的数组 一维扁平化 哈希值。也就是说,对于每个键或值 这是一个数组,提取其元素 进入新阵列。不像 数组#flatten,此方法没有 默认情况下递归展平。如果 可选的level参数决定了 递归水平变平。
这是我所知道的最简单的方法:
{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join('&')
# => "a=100&b=200"
答案 1 :(得分:22)
@ elektronaut版本的轻微变化:
您实际上只能放置|e|
而不是|k, v|
,在这种情况下e
是两个元素的数组,您可以调用e.join('=')
。总而言之,你有类似
class Hash
def join(keyvaldelim=$,, entrydelim=$,) # $, is the global default delimiter
map {|e| e.join(keyvaldelim) }.join(entrydelim)
end
end
{a: 100, b: 200}.join('=', '&') # I love showing off the new Ruby 1.9 Hash syntax
# => 'a=100&b=200'
答案 2 :(得分:5)
嗯,你可以用标准方法和数组来做到这一点:
class Hash
def flatten(keyvaldelimiter, entrydelimiter)
self.map { |k, v| "#{k}#{keyvaldelimiter}#{v}" }.join(entrydelimiter)
end
end
您可能也对Rails to_query
method感兴趣。
另外,显然,您可以将"#{k}#{keyvaldelimiter}#{v}"
写为k.to_s + keyvaldelimiter + v.to_s
...
答案 3 :(得分:4)
如果您正在尝试生成url查询字符串,那么您肯定应该使用像activesupport的to_param这样的方法(别名为to_query)。想象一下,如果数据本身有符号或等号,就会出现问题。
to_query负责转义:
>> require 'active_support/core_ext/object'
>> {'a&' => 'b', 'c' => 'd'}.to_query
>> => "a%26=b&c=d"
修改强>
@fahadsadah提出了一个关于不想加载Rails的好处。即使active_support / core_ext / object也会加载71个文件。它还会修补核心类。
轻巧,清洁的解决方案:
require 'rack' # only loads 3 files
{'a&' => 'b', 'c' => 'd'}.map{|pair|
pair.map{|e| Rack::Utils.escape(e.to_s) }.join('=')
}.join('&')
# => "a%26=b&c=d"
逃避是很重要的,否则操作是不可逆的。
答案 4 :(得分:1)
不确定是否有内置方式,但这里有一些较短的代码:
class Hash
def flatten(kvdelim='', entrydelim='')
self.inject([]) { |a, b| a << b.join(kvdelim) }.join(entrydelim)
end
end
puts ({ :a => :b, :c => :d }).flatten('=', '&') # => a=b&c=d
答案 5 :(得分:0)
如何以JSON格式获取它。这样格式很清楚。
有很多适用于ruby的JSON工具。但是从来没有试过它们。但是输出当然会更容易滑入javascript等。可能一行。
虽然在文档方面会有很大的节省,但是你需要更少的钱。