inv = {"C"=>{"CPS"=>{"CP"=>{"name"=>"a"}}}} is my object
我想要
inv = {"C"=>{"CPS"=>{"CP"=>[{"name"=>"a"}]}}}
我试过
inv["C"]["CPS"].inject({}) do |result, (k, v)|
k = Array.wrap(v)
end
=> [{"name"=>"a"}]
但仍然是inv={"C"=>{"CPS"=>{"CP"=>{"name"=>"a"}}}}
尝试map
答案 0 :(得分:3)
另一种选择是使用tap
inv["C"]["CPS"].tap do |h|
h["CP"] = [h["CP"]] #or Array.wrap(h["CP"]) in rails
end
inv
#=> {"C"=>{"CPS"=>{"CP"=>[{"name"=>"a"}]}}}
tap
将生成当前对象,以便您可以对其进行修改。
<强>更新强>
受@ CarySwoveland更广泛应用程序的启发,你也可以使用这样的东西。
class HashWrapper
attr_reader :original_hash
attr_accessor :target_keys
def initialize(h,*target_keys)
@original_hash = h
@target_keys = target_keys
end
def wrapped_hash
@wrapped_hash ||= {}
end
def wrap_me
original_hash.each do |k,v|
value = v.is_a?(Hash) ? HashWrapper.new(v,*target_keys).wrap_me : v
wrapped_hash[k] = wrap(k,value)
end
wrapped_hash
end
private
def wrap(k,v)
target_keys.include?(k) ? [v] : v
end
end
然后实施如下
wrapper = HashWrapper.new(inv,"CP")
wrapper.wrap_me
#=> {"C"=>
{"CPS"=>
{"CP"=>
[
{"name"=>"a"}
]
}
}
}
new_wrapper = HashWrapper.new(inv,"CP","CPS")
new_wrapper.wrap_me
#=> {"C"=>
{"CPS"=>
[
{"CP"=>
[
{"name"=>"a"}
]
}
]
}
}
这假定在层次结构中一直有唯一的键,否则同名的嵌套键将从下到上以相同的方式包装。 e.g。
inv = {"C"=>{"CPS"=>{"CP"=>{"name"=>"a"}},"CP" => "higher level"}}
HashWrapper.new(inv,"CP").wrap_me
#=> {"C"=>
{"CPS"=>
{"CP"=>
[
{"name"=>"a"}
]
},
"CP"=>
[
"higher level"
]
}
}
答案 1 :(得分:0)
这应该这样做:
hash = {"C"=>{"CPS"=>{"CP"=>{"name"=>"a"}}}}
val = hash["C"]["CPS"]["CP"]
val_as_arr = [val] # can optionally call flatten here
hash["C"]["CPS"]["CP"] = val_as_arr
puts hash
# => {"C"=>{"CPS"=>{"CP"=> [{"name" => "a"}] }}}
基本上
此处不需要迭代,即map
或reduce
答案 2 :(得分:0)
我建议你以一种紧凑且易于阅读的方式使用递归,这种方法比只适用于你的特定哈希的解决方案具有更广泛的应用。
def wrap_it(h)
h.each { |k,v| h[k] = v.is_a?(Hash) ? wrap_it(v) : [v] }
h
end
h = { "C"=>{ "CPS"=>{ "CP"=>{ "name"=>"a" } } } }
wrap_it(h)
#=> {"C"=>{"CPS"=>{"CP"=>{"name"=>["a"]}}}}
h = { "C"=>{ "CPS"=>{ "CP"=>{ "CPPS"=> { "name"=>"cat" } } } } }
wrap_it(h)
#=> {"C"=>{"CPS"=>{"CP"=>{"CPPS"=>{"name"=>["cat"]}}}}}
h = { "C"=>{ "CPS"=>{ "CP"=>{ "CPPS"=> { "name"=>"cat" } },
"DP"=>{ "CPPPS"=>"dog" } } } }
wrap_it(h)
#=> {"C"=>{"CPS"=>{"CP"=>{"CPPS"=>{"name"=>["cat"]}}, "DP"=>{"CPPPS"=>["dog"]}}}}