特定のキーの場合、すべての値をハッシュディープ変換します
概要
コミュニティに敬意を表します! 深くネストされたハッシュがあり、指定された特定のキーのすべての値を変換したいと考えています。 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=>[]}
いくつかの解決策があります 最初の1つ:
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=>[]}