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"]]
]

我找到数组元素的键或 x[0] 的方法是使用:

groups .detect{|x,y| y.detect{|o| o == "A0619"} }[0]

有没有更好的方法呢?

4

3 回答 3

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)

通过键直接访问哈希 100 万次比任何一种方法都快得多,因此如果您可以将此数组存储为哈希,则应该使用它(但前提是它不需要每次都转换数组) .

于 2013-09-15T11:45:45.267 回答
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"
于 2013-09-15T11:24:29.913 回答
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"

基准

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)
于 2013-09-15T11:29:06.143 回答