红宝石有效的方式来获取给定值的多个哈希键

前端之家收集整理的这篇文章主要介绍了红宝石有效的方式来获取给定值的多个哈希键前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从给定值获取所有散列键的最有效方式是什么?
my_hash = {"a"=>"aa","b"=>"bb","c"=>"bb"}

我想把散列“bb”作为一个输入值,并将它们的所有键(b,c)作为数组返回

只返回一个键:

my_hash.index("bb")
# returns only b

这有效但似乎效率不高:

my_hash.select{|k,v| v == 'bb' }.map{|i| i[0] }
# returns b and c

我已经阅读了所有的文档.我觉得有一些明显的东西我失踪了.

谢谢!

更新:

我结束了切换哈希创建的键和值,并使用数组的值.这是一个更有效的解决方案.如果需要,请参阅下面的最佳方法来进行价值查询.

新结构:

my_hash = {"aa"=>["a"],"bb"=>["b","c"]}

解决方法

稍微快一点
my_hash.map{ |k,v| v=='bb' ? k : nil }.compact

较小的哈希和单个查询的速度较慢.如果需要为多个值请求反向映射,则更快.如果这对您的应用程序很重要,我建议维护一个反向地图.

rev = Hash.new{ |h,k| h[k]=[] }
my_hash.each{ |k,v| rev[v] << k }
rev['bb']

基准测试:

require 'benchmark'
N = 1_000_000
my_hash = {"a"=>"aa","c"=>"bb"}

Benchmark.bmbm do |x|
  x.report('select/map'){ N.times{
    my_hash.select{|k,v|v=='bb'}.map{|i| i[0]}
  }}
  x.report('select/map/destructure'){ N.times{
    my_hash.select{|k,v|v=='bb'}.map{|k,v| k}
  }}
  x.report('map/compact'){ N.times{
    my_hash.map{|k,v|v=='bb' ? k : nil}.compact        
  }}
  x.report('reverse map'){ N.times{
    rev = Hash.new{|h,k|h[k]=[]}
    my_hash.each{ |k,v| rev[v]<<k }
    rev['bb']
  }}
  x.report('reject'){ N.times{
    my_hash.reject{|k,v|v != "bb"}.keys
  }}
end
#=> Rehearsal ----------------------------------------------------------
#=> select/map               1.950000   0.000000   1.950000 (  1.950137)
#=> select/map/destructure   1.960000   0.010000   1.970000 (  1.963740)
#=> map/compact              1.200000   0.000000   1.200000 (  1.197340)
#=> reverse map              3.660000   0.000000   3.660000 (  3.658245)
#=> reject                   2.110000   0.000000   2.110000 (  2.115805)
#=> ------------------------------------------------ total: 10.890000sec
#=> 
#=>                              user     system      total        real
#=> select/map               1.950000   0.000000   1.950000 (  1.948784)
#=> select/map/destructure   1.970000   0.010000   1.980000 (  1.966636)
#=> map/compact              1.190000   0.000000   1.190000 (  1.192052)
#=> reverse map              3.670000   0.000000   3.670000 (  3.664798)
#=> reject                   2.140000   0.000000   2.140000 (  2.135069)

猜你在找的Ruby相关文章