我有一系列类似于以下的哈希值:
rules = [{
"id" => "artist_name",
"type" => "string",
"field" => "artist_name",
"input" => "text",
"value" => "Underoath",
"operator" => "contains"
},
{
"id" => "bpm",
"type" => "integer",
"field" => "bpm",
"input" => "number",
"value" => 100,
"operator" => "greater"
}]
我正在对此运行find
以选择所需的哈希值:
rules.find {|h| h['id'] == 'artist_name'}
但是我需要针对许多不同的“规则”执行此操作,这感觉有些冗长。
也许这实际上是获取特定“规则”的最有效方法,但我的直觉是有一个Ruby方法可以更好地做到这一点。
如果我只需要编写自己的方法,那很好,但是想看看是否有一种我不熟悉的方法。
那么,有没有办法以更紧凑/更有效的方式来编写rules.find {|h| h['id'] == 'artist_name'}
?
答案 0 :(得分:2)
如果要查找单个值"id"
的哈希,则显然必须执行线性搜索。另一方面,如果您希望对"id"
的不同值进行多次查找,那么明智的做法是使用适当的键创建哈希。
rules = [{
"id" => "artist_name",
"type" => "string",
"field" => "artist_name",
"input" => "text",
"value" => "Underoath",
"operator" => "contains"
},
{
"id" => "bpm",
"type" => "integer",
"field" => "bpm",
"input" => "number",
"value" => 100,
"operator" => "greater"
}]
h = rules.each_with_index.with_object({}) { |(g,i),h| h[g["id"]] = i }
#=> {"artist_name"=>0, "bpm"=>1}
h
的值是rules
的元素(哈希)的索引。因此,"id"=>"bpm"
的哈希值是
rules[h["bpm"]
#=> {"id"=>"bpm", "type"=>"integer", "field"=>"bpm", "input"=>"number",
# "value"=>100, "operator"=>"greater"}
我本可以将h
的元素本身的值rules
进行设置,但这将需要更多的存储空间而又不会显着缩短查找时间。
对于这个问题,目前尚不清楚"id"
的值对于rules
的两个或更多元素是否可以相同。如果是这种情况,h
的键数将少于rules
的元素数,但是问题的措辞表明可以选择具有相同值"id"
的键中的任何哈希值。 / p>
答案 1 :(得分:2)
您可以尝试按id
进行分组,并使其成为要查找的哈希键。例如
grouped_rules = rules.group_by { |r| r["id"] }
# => {"artist_name"=>[{"id"=>"artist_name", "type"=>"string", "field"=>"artist_name", "input"=>"text", "value"=>"Underoath", "operator"=>"contains"}], "bpm"=>[{"id"=>"bpm", "type"=>"integer", "field"=>"bpm", "input"=>"number", "value"=>100, "operator"=>"greater"}]}
grouped_rules["artist_name"]
# => [{"id"=>"artist_name", "type"=>"string", "field"=>"artist_name", "input"=>"text", "value"=>"Underoath", "operator"=>"contains"}]
这绝对是更紧凑和可读的,但是它是否“有效”取决于您打算如何评估/评估它。这并不能提高内存效率,但是如果您以前经常使用find
,则应该更快。