如何递归地将作为符号的Ruby Hashes的键转换为String

时间:2016-08-31 03:21:32

标签: ruby recursion hash

假设我有以下哈希或嵌套哈希:

h = { :a1 => { :b1 => "c1" },
      :a2 => { :b2 => "c2"},
      :a3 => { :b3 => "c3"} }

我想创建一个方法,将哈希作为参数,并递归地将所有键(符号为例如:a1的键)转换为字符串(例如"a1")。到目前为止,我已经提出了以下方法,它不起作用并返回{"a1"=>{:b1=>"c1"}, "a2"=>{:b2=>"c2"}, "a3"=>{:b3=>"c3"}}。:

def stringify_all_keys(hash)
    stringified_hash = {}
    hash.each do |k, v|
        stringified_hash[k.to_s] = v
        if v.class == Hash
            stringify_all_keys(stringified_hash[k.to_s])
        end
    end
    stringified_hash
end

我做错了什么以及如何将所有键转换为字符串,如下所示:

{"a1"=>{"b1"=>"c1"}, "a2"=>{"b2"=>"c2"}, "a3"=>{"b3"=>"c3"}}

4 个答案:

答案 0 :(得分:6)

如果您已经使用ActiveSupport或已经开放使用它,那么deep_stringify_keys就是您正在寻找的。

hash = { person: { name: 'Rob', age: '28' } }

hash.deep_stringify_keys
# => {"person"=>{"name"=>"Rob", "age"=>"28"}}

答案 1 :(得分:3)

没有测试过,但看起来是对的:

def stringify_all_keys(hash)
  stringified_hash = {}
  hash.each do |k, v|
    stringified_hash[k.to_s] = v.is_a?(Hash) ? stringify_all_keys(v) : v
  end
  stringified_hash
end

答案 2 :(得分:0)

如果您的值是字符串,数字等基本对象,请快速输入:

require 'json'
JSON.parse(JSON.dump(hash))

答案 3 :(得分:0)

使用纯红宝石代码,以下代码可能会有所帮助。 您可以猴子将其修补到红宝石哈希中,以像这样my_hash.deeply_stringfy_keys来使用 但是,我不建议使用猴子分批红宝石。

您可以调整方法以提供其deeply_strigify_keys!(爆炸)版本。

如果您想使用其他方法而不进行递归字符串化或控制字符串化水平,请考虑重新编写以下方法逻辑,以便考虑上述其他变体,使其更好地编写。

def deeply_stringify_keys(hash)
  stringified_hash = {}
  hash.each do |k, v|
    if v.is_a?(Hash)
      stringified_hash[k.to_s] = deeply_stringify_keys(v)
    elsif v.is_a?(Array)
      stringified_hash[k.to_s] = v.map {|i| i.is_a?(Hash)? deeply_stringify_keys(i) : i}
    else
      stringified_hash[k.to_s] = v
    end
  end
  stringified_hash
end