Ruby中的嵌套哈希元素

wa7juj8i  于 12个月前  发布在  Ruby
关注(0)|答案(4)|浏览(95)

我有一个Ruby数组,看起来像这样。

arr = [
  { "dag"=>{
      "tasks"=>[
        { "arguments"=>{
            "parameters"=>[
              { "name"=>"inputJson",
                "value"=>"{{workflow.parameters.inputJson}}"
              }
            ]
          },
          "name"=>"build-handler-workflow",
          "template"=>"build-handler-workflow"
        }
      ]
    },
    "name"=>"dag-build-handler-workflow"
  },
  { "container"=>{
      "args"=>[
        "{{inputs.parameters.inputJson}}"
      ],
      "command"=>["cowsay"],
      "image"=>"docker/whalesay:latest",
      "resources"=>{
        "requests"=>{
          "cpu"=>"100m",
          "memory"=>"100Mi"
        }
      }
    },
    "inputs"=>{
      "parameters"=>[
        {"name"=>"inputJson"}
      ]
    },
    "metadata"=>{
      "annotations"=>{
        "workflows.argoproj.io/progress"=>"0/10000"
      }
    },
    "name"=>"build-handler-workflow",
    "synchronization"=>{
      "semaphore"=>{
        "configMapKeyRef"=>{
          "key"=>"template",
          "name"=>"build-handler-config"
        }
      }
    }
  }
]

我该如何迭代这个数组哈希,这样我就可以只得到图像字段。可能是这样的

p arr['spec']['templates']['container']['image']
"image"=>"docker/whalesay:latest"

我尝试了map方法来访问hash值。无法得到有效的结果。

p arr.map{|e|"#{e["container"]}"}
["", "{\"args\"=>[\"{{inputs.parameters.inputJson}}\"], \"command\"=>[\"cowsay\"], \"image\"=>\"docker/whalesay:latest\", \"resources\"=>{\"requests\"=>{\"cpu\"=>\"100m\", \"memory\"=>\"100Mi\"}}}"]
olmpazwi

olmpazwi1#

你可以使用它,dig在浏览哈希值时也很有用

images = []
arr.each do |item|
  img = item.dig("container", "image")
  images << img unless img.nil?
end

p images
pokxtpni

pokxtpni2#

arr=[{"dag"=>{"tasks"=>[{"arguments"=>{"parameters"=>[{"name"=>"inputJson", "value"=>"{{workflow.parameters.inputJson}}"}]}, "name"=>"build-handler-workflow", "template"=>"build-handler-workflow"}]}, "name"=>"dag-build-handler-workflow"}, {"container"=>{"args"=>["{{inputs.parameters.inputJson}}"], "command"=>["cowsay"], "image"=>"docker/whalesay:latest", "resources"=>{"requests"=>{"cpu"=>"100m", "memory"=>"100Mi"}}}, "inputs"=>{"parameters"=>[{"name"=>"inputJson"}]}, "metadata"=>{"annotations"=>{"workflows.argoproj.io/progress"=>"0/10000"}}, "name"=>"build-handler-workflow", "synchronization"=>{"semaphore"=>{"configMapKeyRef"=>{"key"=>"template", "name"=>"build-handler-config"}}}}]

代码

arr.each do |hash|
  if hash['container']
    puts hash['container']['image']
  end
end

或者你可以用挖掘法

arr.each { |hash| puts hash.dig('container', 'image') if hash['container'] }

输出

docker/whalesay:latest
izkcnapc

izkcnapc3#

如果你不知道在一个给定的数组或哈希(这里是一个数组)中的哪个嵌套哈希中可以找到一个给定的键,并且想要返回一个包含整个给定对象中该键的值的数组,你可以使用下面的递归方法。

def doit(obj, key)
  case obj
  when Array
    obj.each_with_object([]) do |o, arr|
      if [Array, Hash].include?(o.class)
        res = doit(o, key)
        res.each { |v| arr << v }
      end  
    end
  when Hash
    obj.each_with_object([]) do |(k,v), arr|
      if k == key
        arr << v
      elsif [Array, Hash].include?(v.class)
        res = doit(v, key)
        res.each { |v| arr << v }
      end
    end
  end
end
doit(arr, "image")
  #=> ["docker/whalesay:latest"]
doit(arr, "name")
  #=> ["inputJson", "build-handler-workflow", "dag-build-handler-workflow",
  #    "inputJson", "build-handler-workflow", "build-handler-config"]
doit(arr[0]["dag"]["tasks"], "name")
  #=> ["inputJson", "build-handler-workflow"]
doit(arr, "inputs")
  #=> [{"parameters"=>[{"name"=>"inputJson"}]}]
abithluo

abithluo4#

非常感谢您提供所有这些替代方案,所有这些方法都很好,但我更喜欢这一个:

images = arr.filter_map { |e| e.dig("container", "image") }

我可以从数组中获取数据。

相关问题