代码之家  ›  专栏  ›  技术社区  ›  johncssjs

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

  •  0
  • johncssjs  · 技术社区  · 3 年前

    我有下面的例子

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

    我想深度转换这个匹配中的值 seller35 。但是,仅限于第一次出现。因此 b: "seller35" "5.5"=>"seller35" 应保持完整。

    理想情况下,对于数组中的键、值和/或元素。

    我看了看: https://apidock.com/rails/v6.0.0/Hash/_deep_transform_keys_in_object 寻找灵感,但无法找到解决方案。这对所有人都有用

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

    谢谢

    0 回复  |  直到 3 年前
        1
  •  3
  •   Dogbert    3 年前

    您可以创建 done 布尔值,用于跟踪是否已经完成替换,并从块中返回适当的值:

    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: "")
    

    输出:

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