如果数组中存在键,如何从另一个散列中获得散列

时间:2022-12-07 13:35:35

I have a hash, say:

我有一个散列,说:

hash1 ={1=>"a",2=>"b",3=>"c",4=>"d"}

and an array, say:

一个数组,说:

arr=[2,3]

and I have to find a resultant hash like:

我需要找到一个合成哈希,比如

hash2={2="b",3=>"c"}

That is, the resultant hash must contain only those key-value pairs whose keys are present in the given array. Is it possible to do this without a loop?

也就是说,生成的散列必须只包含键值对,其键值在给定数组中。有没有可能做到这一点而不做一个循环?

5 个解决方案

#1


7  

The following will do what you want but is destructive to the original hash1.

下面的代码将执行您想要的操作,但是对原始的hash1是破坏性的。

hash2 = hash1.keep_if {|k,v| arr.include? k}

The following will do what you want but keeps hash1 as it originally was.

下面将执行您想要的操作,但是保持hash1与原来一样。

hash2 = hash1.select {|k,v| arr.include? k}

#2


4  

  hash1.select {|k,v| arr.member? k}  # {2=>"b", 3=>"c"}

#3


2  

Are you looking for something like this?

你在找这样的东西吗?

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

I know you said no loop, but this is as much close as I could get

我知道你说没有环路,但这是我能得到的最接近的

#4


1  

Benchmark for all answers so far:

迄今为止所有答案的基准:

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

Results:

结果:

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

#5


1  

if you are using rails, try

如果您正在使用rails,请尝试

hash2 = hash1.sliec(*arr)

if you are just using ruby, try this

如果您只是在使用ruby,那么试试这个

hash2 = hash1.select {|k, v| arr.include?(k) }

#1


7  

The following will do what you want but is destructive to the original hash1.

下面的代码将执行您想要的操作,但是对原始的hash1是破坏性的。

hash2 = hash1.keep_if {|k,v| arr.include? k}

The following will do what you want but keeps hash1 as it originally was.

下面将执行您想要的操作,但是保持hash1与原来一样。

hash2 = hash1.select {|k,v| arr.include? k}

#2


4  

  hash1.select {|k,v| arr.member? k}  # {2=>"b", 3=>"c"}

#3


2  

Are you looking for something like this?

你在找这样的东西吗?

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

I know you said no loop, but this is as much close as I could get

我知道你说没有环路,但这是我能得到的最接近的

#4


1  

Benchmark for all answers so far:

迄今为止所有答案的基准:

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

Results:

结果:

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

#5


1  

if you are using rails, try

如果您正在使用rails,请尝试

hash2 = hash1.sliec(*arr)

if you are just using ruby, try this

如果您只是在使用ruby,那么试试这个

hash2 = hash1.select {|k, v| arr.include?(k) }