在Ruby中将散列变为string
有没有办法将一个哈希平展到一个string,键和值之间的可选分隔符和键/值对?
例如, 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'
谢谢
我不会覆盖已经定义的.flatten
:
返回一个新的数组,这个散列的一维平坦化。 也就是说,对于数组中的每个键或值,将其元素提取到新数组中。 与数组#平展不同,此方法默认情况下不会以recursion方式平展。 如果可选的级别参数确定recursion级别扁平化。
这是我知道的最简单的方法:
{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join('&') # => "a=100&b=200"
@ 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'
那么,你可以用标准方法和数组来做到这一点:
class Hash def flatten(keyvaldelimiter, entrydelimiter) self.map { |k, v| "#{k}#{keyvaldelimiter}#{v}" }.join(entrydelimiter) end end
您可能也对Rails to_query
方法感兴趣。
另外,显然,你可以写成"#{k}#{keyvaldelimiter}#{v}"
作为k.to_s + keyvaldelimiter + v.to_s
…
如果你想要生成一个URL查询string,你肯定应该使用像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"
逃脱是重要的,否则操作是不可逆的。
不知道是否有一个内置的方式,但这里有一些较短的代码:
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
怎么得到它在JSON格式。 这样的格式是明确的。
有很多的JSON工具的ruby。 虽然从来没有尝试过。 但是输出当然会滑入javascript等等。 可能一行。
大量的节省,虽然将在文件,因为你将需要less得多。