简体   繁体   English

如何仅在第一次出现时深度转换散列/数组中的键或值

[英]How can I deep transform key or value in a hash/array only for the first occurence

I have the following example我有以下示例

 input = {
    "books2" => [1, {a: 1, b: "seller35" }],
    "books3" => { "a" =>[{"5.5"=>"seller35", "6.5" => "foo"}]}
    }

And I would like to deep transform values in this has that matches seller35 .我想深入转换 this has 匹配seller35的值。 However, only for the first occurrence.但是,仅限于第一次出现。 So for b: "seller35" .所以对于b: "seller35" "5.5"=>"seller35" should stay intact. "5.5"=>"seller35"应该保持不变。

Ideally, for key, value and/or element in array.理想情况下,对于数组中的键、值和/或元素。

I looked at: https://apidock.com/rails/v6.0.0/Hash/_deep_transform_keys_in_object for inspiration but couldn't figure out a solution.我查看了: https://apidock.com/rails/v6.0.0/Hash/_deep_transform_keys_in_object寻找灵感,但找不到解决方案。 That does it for all这对所有人都有效

input.deep_transform_values { |value| value == "seller35" ? "" : value }
=> {"books2"=>[1, {:a=>1, :b=>""}], "books3"=>{"a"=>[{"5.5"=>"", "6.5"=>"foo"}]}}

Thanks!谢谢!

You can create a done boolean value to keep track of whether a replacement has been done or not yet and return an appropriate value from the block:您可以创建一个done boolean 值来跟踪替换是否已经完成,并从块中返回适当的值:

require "active_support/core_ext/hash/deep_transform_values"

def deep_transform_values_once(hash:, old_value:, new_value:)
  done = false
  hash.deep_transform_values do |value|
    if !done && value == old_value
      done = true
      new_value
    else
      value
    end
  end
end

input = {
  "books2" => [1, { a: 1, b: "seller35" }],
  "books3" => { "a" => [{ "5.5" => "seller35", "6.5" => "foo" }] },
}

p deep_transform_values_once(hash: input, old_value: "seller35", new_value: "")

Output: Output:

{"books2"=>[1, {:a=>1, :b=>""}], "books3"=>{"a"=>[{"5.5"=>"seller35", "6.5"=>"foo"}]}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM