根据另一个哈希的子集从哈希集合中选择哈希

时间:2015-09-04 21:37:03

标签: ruby hash

鉴于我有哈希:

cmd.ExecuteNonQuery()

我还有另一个哈希:

Grp1:
    key1: value1
    key2: value2
    key3: value3
Grp2:
    key1: value4
    key2: value2
    key3: value5

我想在第一组哈希中搜索并选择 key1: value4 key2: value2 ,因为Grp2' key1:value4符合条件。我该怎么做?

注意:我尝试使用Grp2命令并尝试通过引用文档提供的一些逻辑。我的意图不是获取示例代码而只是提示。对不起,如果我的问题听起来像我要求代码。

1 个答案:

答案 0 :(得分:3)

你所说的第一个哈希不是哈希。实际上,它不是任何类型的Ruby对象。如果它是一个哈希,你需要这样写:

g = { :Grp1 => { key1: value1, key2: value2, key3: value3 },
      :Grp2 => { key1: value4, key2: value2, key3: value5 } }

由于键都是符号,因此您可以使用语法:

g = { Grp1: { key1: value1, key2: value2, key3: value3 },
      Grp2: { key1: value4, key2: value2, key3: value5 } }

value1(和value2等等)必须是变量或方法,但你没有给它们它的值(如果它是一个变量)或它的返回值是(如果是的话)方法),所以我将用文字替换那些变量或方法:

g = { Grp1: { key1: 7, key2: 4, key3: 'cat' },
      Grp2: { key1: 1, key2: 3, key3: 'dog' } }

你的第二个哈希:

h = { :key1 => value4, :key2 => value2 }

有同样的问题,所以我将其替换为:

h = { :key1 => 1, :key2 => 3 }

可以表达:

h = { key1: 1, key2: 3 }

假设我所写的内容是正确的,我们可以使用方法Hash#keysHash#key?Enumerable#findEnumerable#all?编写如下方法:

def doit(g, h)
  hkeys = h.keys
  puts "hkeys=#{hkeys}"
  g.find do |k,v|
    puts "k=#{k}"
    puts "v=#{v}"
    hkeys.all? do |j|
      puts "  v.key?(#{j})=#{v.key?(j)}"
      puts "  v[#{j}]==#{h[j]}: #{v[j]==h[j]}"
      v.key?(j) && v[j] == h[j]
    end
  end
end

我添加了一些puts语句,因此您可以看到计算结果。对于上面定义的gh(使用文字值):

doit(g,h)  
hkeys=[:key1, :key2]
k=Grp1
v={:key1=>7, :key2=>4, :key3=>"cat"}
  v.key?(key1)=true
  v[key1]==1: false
k=Grp2
v={:key1=>1, :key2=>3, :key3=>"dog"}
  v.key?(key1)=true
  v[key1]==1: true
  v.key?(key2)=true
  v[key2]==3: true
  #=> [:Grp2, {:key1=>1, :key2=>3, :key3=>"dog"}] 

在删除puts语句并做一个小改动后,我会写这样的方法:

def doit(g, h)
  hkeys = h.keys
  g.find { |_,v| hkeys.all? { |j| v.key?(j) && v[j] == h[j] } }
end

小变化是我用变量k替换了块变量_,以引起人们注意我在块中没有使用它的事实。

有很多方法可以编写此方法。这是另一个,使用方法Hash#values_at

def doit(g, h)
  hkeys = h.keys
  hvalues = h.values
  g.find { |_,v| v.values_at(*hkeys) == hvalues }
end