我有一个哈希,说:
hash1 ={1=>"a",2=>"b",3=>"c",4=>"d"}
和一个数组,说:
arr=[2,3]
我必须找到一个结果哈希,如:
hash2={2="b",3=>"c"}
也就是说,生成的散列必须只包含给定数组中存在键的键值对。没有循环可以做到这一点吗?
我有一个哈希,说:
hash1 ={1=>"a",2=>"b",3=>"c",4=>"d"}
和一个数组,说:
arr=[2,3]
我必须找到一个结果哈希,如:
hash2={2="b",3=>"c"}
也就是说,生成的散列必须只包含给定数组中存在键的键值对。没有循环可以做到这一点吗?
以下将做你想要的,但会破坏原来的hash1
.
hash2 = hash1.keep_if {|k,v| arr.include? k}
以下将做你想做的,但保持hash1
原来的样子。
hash2 = hash1.select {|k,v| arr.include? k}
hash1.select {|k,v| arr.member? k} # {2=>"b", 3=>"c"}
你在寻找这样的东西吗?
1.9.3p392 :001 > hash1 ={1=>"a",2=>"b",3=>"c",4=>"d"}
=> {1=>"a", 2=>"b", 3=>"c", 4=>"d"}
1.9.3p392 :002 > arr=[2,3]
=> [2, 3]
1.9.3p392 :003 > hash2 = hash1.keep_if{|key, value| arr.include?(key)}
=> {2=>"b", 3=>"c"}
我知道你说没有循环,但这已经尽可能接近了
到目前为止所有答案的基准:
require 'fruity'
hash1 = Hash[[*1..10000].zip[*1.10000]]
arr = 1.upto(1000).select(&:odd?)
compare do
keep_if_include do
hash2 = hash1.dup.keep_if {|k,v| arr.include? k}
end
values_at_zip do
hash2 = Hash[arr.zip(hash1.dup.values_at(*arr))]
end
select_member do
hash2 = hash1.dup.select {|k,v| arr.member? k}
end
end
结果:
Running each test 4096 times. Test will take about 17 seconds.
select_member is faster than keep_if_include by 2x ± 0.1
keep_if_include is faster than values_at_zip by 410x ± 100.0
如果您使用的是导轨,请尝试
hash2 = hash1.sliec(*arr)
如果你只是使用红宝石,试试这个
hash2 = hash1.select {|k, v| arr.include?(k) }