Ruby连接一个散列和一个列表+剩余值

Ruby连接一个散列和一个列表+剩余值,ruby,arrays,algorithm,hash,Ruby,Arrays,Algorithm,Hash,我想在它的键上加入一个散列和一个列表 例如: b列表的元素将始终以哈希形式出现 我想用散列连接列表并保留散列的值。因此,我需要得到以下信息: c={"aa"=>[1,2],"c"=>[6,7,8]} 最快的方法是什么?我的a哈希最多可以包含110.000个密钥。 提前谢谢 a = {"aa"=>[1, 2], "bbb"=>[3, 4, 5], "c"=>[6, 7, 8], "hh"=>[9]} b = ["aa", "c"] a.select{|k,

我想在它的键上加入一个散列和一个列表 例如:

b列表的元素将始终以哈希形式出现

我想用散列连接列表并保留散列的值。因此,我需要得到以下信息:

c={"aa"=>[1,2],"c"=>[6,7,8]}
最快的方法是什么?我的a哈希最多可以包含110.000个密钥。 提前谢谢

a = {"aa"=>[1, 2], "bbb"=>[3, 4, 5], "c"=>[6, 7, 8], "hh"=>[9]} 
b = ["aa", "c"] 
a.select{|k,v| b.include? k}
#=> {"aa"=>[1, 2], "c"=>[6, 7, 8]} 

你应该考虑使用SET,因为它在语义上是正确的,并且会比从ARRAYEXIT中的线性搜索更好地执行。

你应该考虑使用SET,因为它在语义上是正确的,并且会比从ARRAYEXIT中的线性搜索更好地执行。 c=b.reduce{}{{备忘录,x{备忘录[x]=a[x];备忘录} =>{aa=>[1,2],c=>[6,7,8]} [编辑]这里是一些策略的基准:减少、每个和设置:

需要“基准” 需要“设置” a={aa=>[1,2],bbb=>[3,4,5],c=>[6,7,8],hh=>[9]} b=[aa,c] n=1_000 Benchmark.bm8 do|x| x、 reportreduce:{n.times{b.reduce{}{{memo,x}memo[x]=a[x];memo}} x、 reporteach:{n.times{c={};b.each{key}c[key]=a[key]} x、 报告集:{n.times{bset=Set.new['aa','c'];a.select{k,v{bset.include?k} 终止 看起来对于这个愚蠢的基准来说,每种方法都是最有效的:

               user     system      total        real
reduce:    0.000000   0.000000   0.000000 (  0.003384)
each:      0.010000   0.000000   0.010000 (  0.002549) # <-- winner!
set:       0.010000   0.000000   0.010000 (  0.012549)
c=b.reduce{}{{备忘录,x{备忘录[x]=a[x];备忘录} =>{aa=>[1,2],c=>[6,7,8]} [编辑]这里是一些策略的基准:减少、每个和设置:

需要“基准” 需要“设置” a={aa=>[1,2],bbb=>[3,4,5],c=>[6,7,8],hh=>[9]} b=[aa,c] n=1_000 Benchmark.bm8 do|x| x、 reportreduce:{n.times{b.reduce{}{{memo,x}memo[x]=a[x];memo}} x、 reporteach:{n.times{c={};b.each{key}c[key]=a[key]} x、 报告集:{n.times{bset=Set.new['aa','c'];a.select{k,v{bset.include?k} 终止 看起来对于这个愚蠢的基准来说,每种方法都是最有效的:

               user     system      total        real
reduce:    0.000000   0.000000   0.000000 (  0.003384)
each:      0.010000   0.000000   0.010000 (  0.002549) # <-- winner!
set:       0.010000   0.000000   0.010000 (  0.012549)
遍历数组:

a={"aa"=>[1, 2], "bbb"=>[3, 4, 5], "c"=>[6, 7, 8], "hh"=>[9]}
b=["aa","c"]
c = {}
b.each{|key| c[key] = a[key]}
#=>{"aa"=>[1, 2], "c"=>[6, 7, 8]}
遍历数组:

a={"aa"=>[1, 2], "bbb"=>[3, 4, 5], "c"=>[6, 7, 8], "hh"=>[9]}
b=["aa","c"]
c = {}
b.each{|key| c[key] = a[key]}
#=>{"aa"=>[1, 2], "c"=>[6, 7, 8]}
另一种选择:

Hash[b.zip(a.values_at(*b))]
# => {"aa"=>[1, 2], "c"=>[6, 7, 8]}
另一种选择:

Hash[b.zip(a.values_at(*b))]
# => {"aa"=>[1, 2], "c"=>[6, 7, 8]}
基准

require 'benchmark'
require 'set'
a = {}
("aaaa".."gggg").each{|k| a[k]=true}
p a.size #=>109675
b = a.keys.sample(1000) #try other numbers

b_set=b.to_set
c={}

Benchmark.bm(15) do |x|
  x.report("select"){a.select{|k,v| b.include? k}}
  x.report("set"){a.select{|k,v| b_set.include? k}}
  x.report("array.each"){b.each{|key| c[key] = a[key]}}
  x.report("array.inject"){b.reduce({}) { |memo,x| memo[x]=a[x]; memo }}
  x.report("assoc"){Hash[b.map{|i| a.assoc(i)}]}
  x.report("values_at"){Hash[b.zip(a.values_at(*b))]}
end
古代笔记本电脑上的输出:

                      user     system      total        real
select           22.860000   0.030000  22.890000 ( 24.454489)
set               0.100000   0.000000   0.100000 (  0.115898)
array.each        0.000000   0.000000   0.000000 (  0.001589)
array.inject      0.000000   0.000000   0.000000 (  0.001265)
assoc            26.090000   0.060000  26.150000 ( 29.330769)
values_at         0.000000   0.000000   0.000000 (  0.001455)
基准

require 'benchmark'
require 'set'
a = {}
("aaaa".."gggg").each{|k| a[k]=true}
p a.size #=>109675
b = a.keys.sample(1000) #try other numbers

b_set=b.to_set
c={}

Benchmark.bm(15) do |x|
  x.report("select"){a.select{|k,v| b.include? k}}
  x.report("set"){a.select{|k,v| b_set.include? k}}
  x.report("array.each"){b.each{|key| c[key] = a[key]}}
  x.report("array.inject"){b.reduce({}) { |memo,x| memo[x]=a[x]; memo }}
  x.report("assoc"){Hash[b.map{|i| a.assoc(i)}]}
  x.report("values_at"){Hash[b.zip(a.values_at(*b))]}
end
古代笔记本电脑上的输出:

                      user     system      total        real
select           22.860000   0.030000  22.890000 ( 24.454489)
set               0.100000   0.000000   0.100000 (  0.115898)
array.each        0.000000   0.000000   0.000000 (  0.001589)
array.inject      0.000000   0.000000   0.000000 (  0.001265)
assoc            26.090000   0.060000  26.150000 ( 29.330769)
values_at         0.000000   0.000000   0.000000 (  0.001455)

这似乎更快,但对于110.000个键,内存会更大,如果需要交换,则速度会更慢。实际上,hash.select会遍历所有110.000个键;这只会搜索所需的子集,而散列在搜索中非常有效。这似乎更快,但对于110.000个键,内存是可扩展的,如果需要交换,则实际上散列速度会较慢。select会遍历所有110.000个键;这只搜索所需的子集,而哈希在search.OMG中非常有效!根据你的基准,assoc花费的时间太多了。我很惊讶天啊!根据你的基准,assoc花费的时间太多了。我很惊讶请注意,这可能更快。请注意,这可能更快。作为答案发布的我的基准,使用大约110.000的捕获哈希和数组捕获1000,将您的代码显示为赢家。作为答案发布的我的基准,使用大约110.000的捕获哈希和数组捕获1000,将您的代码显示为赢家。