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



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

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

我想创建一个以hash为参数的方法,并递归地将所有键(符号为例如:a1的键(转换为String(例如"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"}}

如果您已经在使用ActiveSupport或对使用它持开放态度,那么deep_stringify_keys就是您想要的。

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

如果您的值是字符串、数字等基本对象,则快速'n'dirty:

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

没有对此进行测试,但看起来大致正确:

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

使用普通的ruby代码,下面的代码可能会有所帮助。您可以将它猴子式地修补到ruby Hash中,以便像这样使用my_hash.deeply_stringfy_keys但是,我不建议monkey批处理ruby。

您可以调整方法以提供deeply_strigify_keys!(bang(版本的

如果你想制作一个不递归字符串化的不同方法,或者控制字符串化的级别,那么考虑重写下面的方法逻辑,这样你就可以更好地考虑上面提到的其他变体。

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

最新更新