假设我有一个像这样的数组:
groups = [
["G1", ["A0640", "A0660", "A0647", "A0643", "A0604", "A0644"]],
["G2", ["A1609","A1611","A1608","A1610"]],
["G3", ["A0613", "A0619", "A0637", "A0636"]],
["G4", ["A0646", "A0610", "A0645"]],
["G5", ["A0616", "A0611", "A0638", "A0606", "A0602", "A0639", "A0626", "A0605"]]
]
我要做的是找到数组元素的键或x [0]:使用:
groups .detect{|x,y| y.detect{|o| o == "A0619"} }[0]
有没有更好的方法呢?
答案 0 :(得分:1)
我想我们可以假设“更好”你的意思是“更快”?如果速度(而不是语法)是问题,那么您可以使用不同的建议解决方案轻松测量需要多长时间:
Benchmark.bm(8) do |x|
x.report("detect:") do
1_000_000.times { groups.detect{|x,y| y.detect{|o| o == "A0619"} }[0] }
end
x.report("include:") do
1_000_000.times { groups.detect{|x,y| y.include? "A0619" }[0] }
end
x.report("rassoc:") do
1_000_000.times { groups.map(&:flatten).rassoc("A0613").first }
end
x.report("hashwc:") do
1_000_000.times do
hash = Hash[groups.flat_map { |key, values| values.map { |value| [value, key] } }]
hash['A0619']
end
end
x.report("hash-x:") do
1_000_000.times do
Hash[groups].detect{|_,v| v.include? "A0619" }.first
end
end
end
user system total real
detect: 6.480000 0.020000 6.500000 ( 6.523376)
include: 2.650000 0.000000 2.650000 ( 2.658573)
rassoc: 9.920000 0.150000 10.070000 ( 10.099147)
hashwc: 21.440000 0.040000 21.480000 ( 21.543540)
hash-x: 5.690000 0.010000 5.700000 ( 5.725335)
通过密钥直接访问哈希值的方式比任何一种方法都要快,所以如果你可以将这个数组存储为哈希值,你应该去做它(但只有在它不需要转换数组时)每一次)。
答案 1 :(得分:0)
您可以使用Enumerable#include?
代替Enumerable#detect
:
groups.detect{|x,y| y.include? "A0619" }[0]
# => "G3"
如果您需要多次执行此操作,最好创建一个哈希:
groups = [
["G1", ["A0640", "A0660", "A0647", "A0643", "A0604", "A0644"]],
["G2", ["A1609","A1611","A1608","A1610"]],
["G3", ["A0613", "A0619", "A0637", "A0636"]],
["G4", ["A0646", "A0610", "A0645"]],
["G5", ["A0616", "A0611", "A0638", "A0606", "A0602", "A0639", "A0626", "A0605"]]
]
hash = Hash[groups.flat_map { |key, values| values.map { |value| [value, key] } }]
hash['A0619']
# => "G3"
答案 2 :(得分:0)
这是怎么回事?
groups = [
["G1", ["A0640", "A0660", "A0647", "A0643", "A0604", "A0644"]],
["G2", ["A1609","A1611","A1608","A1610"]],
["G3", ["A0613", "A0619", "A0637", "A0636"]],
["G4", ["A0646", "A0610", "A0645"]],
["G5", ["A0616", "A0611", "A0638", "A0606", "A0602", "A0639", "A0626", "A0605"]]
]
Hash[groups].detect{|_,v| v.include? "A0619" }.first
# => "G3"
<强>更新强>
groups = [
["G1", ["A0640", "A0660", "A0647", "A0643", "A0604", "A0644"]],
["G2", ["A1609","A1611","A1608","A1610"]],
["G3", ["A0613", "A0619", "A0637", "A0636"]],
["G4", ["A0646", "A0610", "A0645"]],
["G5", ["A0616", "A0611", "A0638", "A0606", "A0602", "A0639", "A0626", "A0605"]]
]
groups[groups.index{|_,a| a.include? "A0619"}][0]
# => "G3"
<强>的BenchMark 强>
require "benchmark"
groups = [
["G1", ["A0640", "A0660", "A0647", "A0643", "A0604", "A0644"]],
["G2", ["A1609","A1611","A1608","A1610"]],
["G3", ["A0613", "A0619", "A0637", "A0636"]],
["G4", ["A0646", "A0610", "A0645"]],
["G5", ["A0616", "A0611", "A0638", "A0606", "A0602", "A0639", "A0626", "A0605"]]
]
Benchmark.bm(8) do |x|
x.report("falsetru:") do
1_000_000.times { groups.detect{|x,y| y.detect{|o| o == "A0619"} }[0] }
end
x.report("Arup1") do
1_000_000.times { groups[groups.index{|_,a| a.include? "A0619"}][0] }
end
x.report("Arup2") do
1_000_000.times do
Hash[groups].detect{|_,v| v.include? "A0619" }.first
end
end
end
<强>输出强>
user system total real
falsetru: 8.860000 0.000000 8.860000 ( 8.885295)
Arup1 2.780000 0.000000 2.780000 ( 2.800791)
Arup2 7.800000 0.000000 7.800000 ( 7.825369)