ruby select元素嵌套哈希相同的键

时间:2014-07-04 03:05:37

标签: ruby hash

我有下面的哈希,我试图获得"值"元素匹配'"年" => " 2014"'和'"期间" => " M06"'

result = {"status"=>"REQUEST_SUCCEEDED", "responseTime"=>28, "message"=>[], "Results"=>{"series"=>[{"seriesID"=>"LNU03034342", "data"=>[{"year"=>"2014", "period"=>"M06", "periodName"=>"June", "value"=>"11.1", "footnotes"=>[{}]}, {"year"=>"2014", "period"=>"M05", "periodName"=>"May", "value"=>"16.8", "footnotes"=>[{}]}, {"year"=>"2014", "period"=>"M04", "periodName"=>"April", "value"=>"18.8", "footnotes"=>[{}]}, {"year"=>"2014", "period"=>"M03", "periodName"=>"March", "value"=>"18.7", "footnotes"=>[{}]}, {"year"=>"2014", "period"=>"M02", "periodName"=>"February", "value"=>"17.6", "footnotes"=>[{}]}, {"year"=>"2014", "period"=>"M01", "periodName"=>"January", "value"=>"16.0", "footnotes"=>[{}]}]}]}}

到目前为止,我已经["结果"] ["系列"] [0] ["数据"]'产生:

{"year"=>"2014", "period"=>"M06", "periodName"=>"June", "value"=>"11.1", "footnotes"=>[{}]}
{"year"=>"2014", "period"=>"M05", "periodName"=>"May", "value"=>"16.8", "footnotes"=>[{}]}
{"year"=>"2014", "period"=>"M04", "periodName"=>"April", "value"=>"18.8", "footnotes"=>[{}]}
{"year"=>"2014", "period"=>"M03", "periodName"=>"March", "value"=>"18.7", "footnotes"=>[{}]}
{"year"=>"2014", "period"=>"M02", "periodName"=>"February", "value"=>"17.6", "footnotes"=>[{}]}
{"year"=>"2014", "period"=>"M01", "periodName"=>"January", "value"=>"16.0", "footnotes"=>[{}]}

现在,这个父哈希的每个元素中的所有键都是相同的,所以我需要通过搜索M06的周期来获得我想要的,选择该元素,然后从元素中获取值。我该怎么做呢?

我意识到技术上我可以采用第一个嵌套的哈希,因为我寻求最高的时期,但这似乎很草率。

1 个答案:

答案 0 :(得分:2)

你可以这样做

result["Results"]["series"][0]["data"].find(->(){ {} }) do |hash|
    hash[period] == 'M06'
end.fetch(value, "period not found")
  

#find - 传递enum中的每个条目以阻止。返回第一个块不为false的块。 如果没有对象匹配,则调用ifnone 并在指定时返回其结果,否则返回nil。

因此,出于任何原因,如果未找到任何哈希的密钥期间'M06'值,那么#find将调用参数我传递给它,就像->() { {} }.call一样,并返回空哈希,否则如果找到'M06'的密钥'period任何哈希,然后将返回哈希。在此返回的哈希上,我调用Hash#fetch方法。

解释这个的例子: -

#!/usr/bin/env ruby

array = {a: 1, b: 2}, { a: 4, b: 11}

def fetch_value(array, search_key, search_value, fetch_key)
  array.find(->(){ {} }) do |h|
    h[search_key] == search_value 
  end.fetch(fetch_key, "#{search_value} is not found for #{search_key}.")
end

fetch_value(array, :a, 11, :b) # => "11 is not found for a."
fetch_value(array, :a, 4, :b) # => 11