象征和替换哈希数组中的哈希值

问题描述

我有一个与此相似的数据结构

  lib_data = {'library'=>[{"type"=>"Books","checkout"=>false,"data"=>[{"type"=>"Books","operator"=>"AND","details"=>{"property"=>"Name","author"=>"%s","name"=>"%s"}},{"type"=>"Books","criteria"=>{"property"=>"Revision","operator"=>"%s","value"=>"%s"}}]}]}

我试图先将所有键组合起来,然后在用%s代替的键中插入值

我能够在Hash类中猴子修补一小段代码,这将使我能够使用类似这样的符号来象征所有哈希值

def symbolize_all_keys
    keys.each do |k|
      key = k.to_sym
      value = delete(k)
      store(key,value)
    end
    self
  end

然后仅使用lib_data.symbolize_all_keys,但这象征着一个

是否有一种更惯用的方式来象征所有按键?

还想要一种将值插入具有%s值的键中的方法吗?

解决方法

您可以递归方式使用Hash#transform_keys!,例如:

def symbolize_all_keys(h)
  if h.is_a? Hash
    h.transform_keys!(&:to_sym)
    h.values.each do |val|
      val.each { |v| symbolize_all_keys(v) } if val.is_a? Array
      symbolize_all_keys(val)
    end
  end
  h
end

symbolize_all_keys(lib_data)

lib_data
#=> {:library=>[{:type=>"Books",:checkout=>false,:data=>[{:type=>"Books",:operator=>"AND",:details=>{:property=>"Name",:author=>"%s",:name=>"%s"}},{:type=>"Books",:criteria=>{:property=>"Revision",:operator=>"%s",:value=>"%s"}}]}]}

对于第二部分,根据密钥,不清楚哪个值替换“%s”。

只是一个想法,与上面的递归类似:

def replace_val(h,new_val = 'new_val')
  if h.is_a? Hash
    h.each do |key,val|
      h[key] = new_val if val == '%s'
      val.each { |v| replace_val(v) } if val.is_a? Array
      replace_val(val)
    end
  end
  h
end

replace_val(lib_data)

lib_data
#=> {:library=>[{:type=>"Books",:author=>"new_val",:name=>"new_val"}},:operator=>"new_val",:value=>"new_val"}}]}]}

在这里您可以访问值的键,但不能访问更高的级别。

,

如果您使用滑轨,则可以使用HashWithIndifferentAccess

您还可以在Rails之外访问此类,需要使用以下内容进行核心扩展:

require "active_support/core_ext/hash/indifferent_access"

2.6.5 :015 > lib_data = {'library'=>[{"type"=>"Books",2.6.5 :016 >           "checkout"=>false,"data"=>[{"type"=>"Books","operator"=>"AND","details"=>{"property"=>"Name","author"=>"%s",2.6.5 :017 >                 "name"=>"%s"}},{"type"=>"Books","criteria"=>{"property"=>"Revision","operator"=>"%s",2.6.5 :018 >                 "value"=>"%s"}}]}]}
 => {"library"=>[{"type"=>"Books","checkout"=>false,"name"=>"%s"}},"value"=>"%s"}}]}]}
2.6.5 :019 > lib_data[:library]
 => nil
2.6.5 :020 > lib_data = lib_data.with_indifferent_access
 => {"library"=>[{"type"=>"Books","value"=>"%s"}}]}]}
2.6.5 :021 > lib_data[:library]
 => [{"type"=>"Books","value"=>"%s"}}]}]