我有一些ruby代码从Jenkins获取一个包含n个项目数组的json。我想要的项目有一个名为" lastBuiltRevision"
的密钥我知道我可以像这样循环遍历数组
actions.each do |action|
if action["lastBuiltRevision"]
lastSuccessfulRev = action["lastBuiltRevision"]["SHA1"]
break
end
end
但是这种感觉非常笨重,并且没有我在使用红宝石时通常会感受到的魔力。
我现在只修了大约一个星期,我觉得我可能会遗漏一些东西,以使这更容易/更快。
有这样的事吗?或者我是否可以手动迭代?
我有点希望像
这样的东西lastSuccessfulRev = action.match("lastBuildRevision/SHA1")
答案 0 :(得分:4)
actions = [
{'dummy' => true },
{'dummy' => true },
{'dummy' => true },
{'lastBuiltRevision' => { "SHA1" => "123abc" }},
{'dummy' => true },
]
actions.find { |h|
h.has_key? 'lastBuiltRevision'
}['lastBuiltRevision']['SHA1']
# => "123abc"
更新
如果没有匹配的项目,上面的代码会抛出NoMethodError
。如果您不想获得例外,请使用以下代码。
rev = actions.find { |h| h.has_key? 'lastBuiltRevision' }
rev = rev['lastBuiltRevision']['SHA1'] if rev
答案 1 :(得分:2)
这是另一种方法,利用Enumerable#find的形式,它接受一个被调用的参数ifnone
,并返回其返回值,如果find
的块从不评估true
。
我假设如果找不到任何一个密钥,该方法将返回nil
。
<强>代码强>
def look_for(actions, k1, k2)
actions.find(->{{k1=>{}}}) { |e| e.key?(k1) }[k1][k2]
end
<强>实施例强>
actions = [{ 'dog'=>'woof' }, { 'lastBuiltRevision'=>{ 'SHA1'=> 2 } }]
look_for(actions, 'lastBuiltRevision', 'SHA1') #=> 2
look_for(actions, 'cat, 'SHA1') #=> nil
look_for(actions, 'lastBuiltRevision', 'cat') #=> nil
<强>解释强>
我已将find
的{{1}}参数设为lambda:
ifnone
这样:
l = ->{{k1=>{}}}
答案 2 :(得分:1)
尝试:
action.map { |a| a["lastBuiltRevision"] }.compact.map { |lb| lb["SHA1"] }.first