2016-07-07 73 views
0

我正在尝试执行类似How to find a hash key containing a matching value的操作,但结构更复杂。在解决这个问题时,使用嵌套地图调用来散列是不成功的。在嵌套散列中查找值

data = {"typeA" => { 
    "statX" => { 
    "funcA" => {"id"=>1, "name"=>"typeA_funcA_statX"}, 
    "funcB" => {"id"=>7, "name"=>"typeA_funcB_statX"} 
    } 
}} 

现在我想找到“typeA_funcB_statX”的ID。在这种情况下,我能够通过使用该名称拆分,以获得ID并获得ID在传统的直接散列引用:

type,func,stat = "typeA_funcB_statX".split("_") 
id = data[type][stat][func]["id"] 

如果名称是一个随机字符串,虽然,我能够找到通过写一个嵌套的每个循环ID(所有name情况下,将横跨哈希唯一):

searchForName = "typeA_funcB_statX" 
id = nil 
data.each do |type,typeData| 
    typeData.each do |stat,statData| 
    statData.each do |func, funcData| 
     id = funcData["id" if funcData["name"] == searchForName 
    end 
    end 
end 

我可以使用findselect方法,当我到达的statData线,但想知道怎么做这更有说服力/更有效率。复杂性使得我的地图调用无法正常工作。我怀疑一个很好的解决方案是嵌套地图的select/find调用,也许是一个反转。

编辑

作为一个更好的例子,当我不能使用name确定任何按键,考虑这个哈希:

data = {"typeA" => { 
    "statX" => { 
    "funcA" => {"id"=>1, "name"=>"theFoo"}, 
    "funcB" => {"id"=>7, "name"=>"someBar"} 
    } 
} } 

现在我想找到的ID “theFoo” - 即键和名称值之间没有关联。

+0

1.你的意思是你想找到“typeA_funcB_statX”的ID(即是一个错字? )?如果“typeA_funcB_stat”确实是你的意思,请解释匹配标准。 2.'data'包含两个你应该修复的错误:a)按照写法,'name'必须是局部变量或方法。如果你的意思是一个文字,把它改为'“name”'或':name'。 b)在最后你错过了一个右括号('}')。一定要检查输入是否正确。正确的格式化有助于获得匹配的'()','[]'和{}'对。 –

+0

对不起,是的 - 一个错字 - 'statX' – Brett

+0

你仍然需要编辑来处理我的第二点。 –

回答

0

发现了一种嵌套的地图做,紧凑和flatten.first:

fnd="theFoo" 
data.map{|t,th|th.map{|s,sh|sh.map{|f,fh|fh["id"]if fh["name"]==fnd}.compact}}.flatten.first 

==> 1 
0
data = { 
    "typeA" => { 
    "statX" => { 
     "funcA" => {"id"=>1, :name=>"typeA_funcA_statX"}, 
     "funcB" => {"id"=>7, :name=>"typeA_funcB_statX"} 
    } 
    } 
} 

我认为这是你在找什么:

str = "typeA_funcB_statX" 

data["typeA"]["statX"].values.find { |h| h[:name] == str }["id"] 
    #=> 7 

如果你不能确定会出现在str"typeA_funcB_statX"这里)比赛,你可以写

val = data["typeA"]["statX"].values.find { |h| h[:name] == str } 
val = val["id"] unless val.nil? 
0

试试这个来找到你需要的'ID',

data.find{ |k,v| k == "typeA"}[1].find{ |k,v| k == "statX"}[1] 
.find{ |k,v| k == "funcB"}[1]["id"] 

==> 7 
+0

嗨Sravan,我不清楚我如何问我的问题 - 我想找到一种方式来获得ID而不指定任何密钥的哈希,即使用map/find。我添加了一个使用散列的新例子。寻找一种单行的方式来找到它,而不是嵌套的'.each'循环。 – Brett