我对社区的尊重! 我有深层嵌套哈希,我想转换所提供的特定键的所有值。像
deep transform values if key == :something
之类的东西
哈希示例:
{:id=>"11ed35b8e53c442ea210c39d6f24bddf",
:createdAt=>"2022-09-16T12:12:55.454Z",
:updatedAt=>"2022-09-16T12:12:55.454Z",
:status=>"ACTIVE",
:description=>"test",
:goals=>
[{:Definitions=>[],
:text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
:status=>"ACTIVE",
:Definitions=>[{:text=>"Search for relics", :status=>"INACTIVE", :id=>"11ec1fc4bd36f876963867013cee2799"}],
:id=>"11e818be2f0157329c76634ee23c1d8f"}],
:healthConcernDefinitions=>[]}
我想转换所有键的所有值
:status
结果必须是:
{:id=>"11ed35b8e53c442ea210c39d6f24bddf",
:createdAt=>"2022-09-16T12:12:55.454Z",
:updatedAt=>"2022-09-16T12:12:55.454Z",
:status=>"TRANSFORMED",
:description=>"test",
:goals=>
[{:Definitions=>[],
:text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
:status=>"TRANSFORMED",
:Definitions=>[{:text=>"Search for relics", :status=>"TRANSFORMED", :id=>"11ec1fc4bd36f876963867013cee2799"}],
:id=>"11e818be2f0157329c76634ee23c1d8f"}],
:healthConcernDefinitions=>[]}
我有几个解决方案 第一个:
hash_to_json = hash.to_json.gsub(/"ACTIVE"|"INACTIVE"/, '"TRANSFORMED"')
JSON.parse(hash_to_json)
第二个:
hash.deep_transform_values { |v| (v == 'ACTIVE' || v == 'INACTIVE') ? 'TRANSFORMED' : v }
两种解决方案都有效,但我不喜欢匹配值,我只想匹配特定的键并在整个哈希中更改它,例如:
hash.deep_transform_keys { |k, v| v = 'TRANSFORMED' if k == :status }
非常感谢!
不幸的是,
Hash#deep_transform_values
仅接受块值,而不接受键。不幸的是 Hash#deep_merge
和 Hash#deep_merge!
没有那么强大
您可以编写自己的方法。这只是想法,你可以改进它
class Hash
def deep_replace(hash)
deep_dup.deep_replace!(hash)
end
def deep_replace!(hash)
each_key do |key|
hash.each do |k, v|
self[key] = v if key == k
end
_replace_object!(self[key], hash)
end
end
private
def _replace_object!(object, hash)
case object
when Hash
object.deep_replace!(hash)
when Array
object.map! { |v| _replace_object!(v, hash) }
else
object
end
end
end
hash = {:id=>"11ed35b8e53c442ea210c39d6f24bddf",
:createdAt=>"2022-09-16T12:12:55.454Z",
:updatedAt=>"2022-09-16T12:12:55.454Z",
:status=>"ACTIVE",
:description=>"test",
:goals=>
[{:Definitions=>[{:text=>"Search for relics", :status=>"INACTIVE", :id=>"11ec1fc4bd36f876963867013cee2799"}],
:text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
:status=>"ACTIVE",
:id=>"11e818be2f0157329c76634ee23c1d8f"}],
:healthConcernDefinitions=>[]}
之后就可以应用了
# Replace one key
hash.deep_replace(status: "TRANSFORMED")
# => {:id=>"11ed35b8e53c442ea210c39d6f24bddf",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"TRANSFORMED",
# :description=>"test",
# :goals=>
# [{:Definitions=>[{:text=>"Search for relics", :status=>"TRANSFORMED", :id=>"11ec1fc4bd36f876963867013cee2799"}],
# :text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"TRANSFORMED",
# :id=>"11e818be2f0157329c76634ee23c1d8f"}],
# :healthConcernDefinitions=>[]}
# Replace few keys
hash.deep_replace(status: "TRANSFORMED", txid: "555", id: "99999999999999999999999999999999")
# => {:id=>"99999999999999999999999999999999",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"TRANSFORMED",
# :description=>"test",
# :goals=>
# [{:Definitions=>[{:text=>"Search for relics", :status=>"TRANSFORMED", :id=>"99999999999999999999999999999999"}],
# :text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"TRANSFORMED",
# :id=>"99999999999999999999999999999999"}],
# :healthConcernDefinitions=>[]}
# Check original (it wasn't changed)
hash
# => {:id=>"11ed35b8e53c442ea210c39d6f24bddf",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"ACTIVE",
# :description=>"test",
# :goals=>
# [{:Definitions=>[{:text=>"Search for relics", :status=>"INACTIVE", :id=>"11ec1fc4bd36f876963867013cee2799"}],
# :text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"ACTIVE",
# :id=>"11e818be2f0157329c76634ee23c1d8f"}],
# :healthConcernDefinitions=>[]}
# Destructive method
hash.deep_replace!(status: "TRANSFORMED", id: "99999999999999999999999999999999")
# => {:id=>"99999999999999999999999999999999",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"TRANSFORMED",
# :description=>"test",
# :goals=>
# [{:Definitions=>[{:text=>"Search for relics", :status=>"TRANSFORMED", :id=>"99999999999999999999999999999999"}],
# :text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"TRANSFORMED",
# :id=>"99999999999999999999999999999999"}],
# :healthConcernDefinitions=>[]}
# Check original (it was changed)
hash
# => {:id=>"99999999999999999999999999999999",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"TRANSFORMED",
# :description=>"test",
# :goals=>
# [{:Definitions=>[{:text=>"Search for relics", :status=>"TRANSFORMED", :id=>"99999999999999999999999999999999"}],
# :text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"TRANSFORMED",
# :id=>"99999999999999999999999999999999"}],
# :healthConcernDefinitions=>[]}
我们可以使用类似于
deep_transform_keys
的实现来实现密钥的条件覆盖。
def deep_overwrite(object, other_h)
case object
when Hash
object.each_with_object({}) do |(key, value), result|
result[key] = other_h[key] || deep_overwrite(value, other_h)
end
when Array
object.map { |e| deep_overwrite(e,other_h) }
else
object
end
end
虽然这不采用块格式(如您的帖子中所示),但根据您的用例,这似乎没有必要。相反,这将简单地覆盖原始 (
object
) 中包含的任何键(嵌套在任何级别)的值,该值也包含在 other_h
中。
在您的情况下称之为
original = {:id=>"11ed35b8e53c442ea210c39d6f24bddf",
:createdAt=>"2022-09-16T12:12:55.454Z",
:updatedAt=>"2022-09-16T12:12:55.454Z",
:status=>"ACTIVE",
:description=>"test",
:goals=>
[{:text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
:status=>"ACTIVE",
:Definitions=>[{:text=>"Search for relics", :status=>"INACTIVE", :id=>"11ec1fc4bd36f876963867013cee2799"}],
:id=>"11e818be2f0157329c76634ee23c1d8f"}],
:healthConcernDefinitions=>[]}
result = deep_overwrite(original,{status: 'TRANSFORMED'})
#=> {:id=>"11ed35b8e53c442ea210c39d6f24bddf",
# :createdAt=>"2022-09-16T12:12:55.454Z",
# :updatedAt=>"2022-09-16T12:12:55.454Z",
# :status=>"TRANSFORMED",
# :description=>"test",
# :goals=>
# [{:text=>"Follows Action Plan Appropriately, Worse or Warning Symptoms",
# :status=>"TRANSFORMED",
# :Definitions=>
# [{:text=>"Search for relics",
# :status=>"TRANSFORMED",
# :id=>"11ec1fc4bd36f876963867013cee2799"}],
# :id=>"11e818be2f0157329c76634ee23c1d8f"}],
# :healthConcernDefinitions=>[]}