在哈希中查找重复键?

时间:2016-09-12 09:21:15

标签: ruby hash unique

为了简化事情,我们假设我有以下的哈希值。

我想找到多个哈希中的键和哈希的名称。理想情况下,我希望最终得到

A is also in  a
A is also in  b
B is also in  a
B is also in  b
D is also in  b
D is also in  c
E is also in  b
E is also in  c

我能想到的唯一方法是:将所有键放在一个数组中,对其进行排序,删除唯一元素,搜索包含剩余数组元素的每个哈希值。

我猜这有点复杂和笨拙。

问题

是否有更简单的方法可以在哈希中找到重复的键?

!/usr/bin/ruby                                                                                          

require 'ap'

a = {}
b = {}
c = {}

a["A"] = 1
a["B"] = 1
a["C"] = 1

b["A"] = 1
b["B"] = 1
b["D"] = 1
b["E"] = 1

c["D"] = 1
c["E"] = 1
c["F"] = 1

3 个答案:

答案 0 :(得分:1)

要找到具有某个键的哈希值,您可以这样做。

def find_key_in list_of_hashes, key
  list_of_hashes.select { |one_hash| one_hash.detect { |k,v| k == key }}
end

这样称呼:

irb(main):016:0> find_key_in [{a: 3, b: 2}, {b: 3, x: 4} ], :x
=> [{:b=>3, :x=>4}]

打印哈希的名称很诡异。 See this question.

答案 1 :(得分:1)

这样的事情?

arr = { 'a' => a, 'b' => b, 'c' =>c}
#=> {"a"=>{"A"=>1, "B"=>1, "C"=>1}, "b"=>{"A"=>1, "B"=>1, "D"=>1, "E"=>1}, "c"=>{"D"=>1, "E"=>1, "F"=>1}}

def my_method(letter, arr)
 arr.map { |el|  "#{letter} is in #{el[0]}" if !el[1]["#{letter}"].nil? }.compact
end

示例:

my_method("A", arr)
#=> ["A is in a", "A is in b"]

答案 2 :(得分:1)

您可以构建另一个哈希来存储每个键及其哈希值:

keys = Hash.new { |hash, key| hash[key] = [] }
a.each_key { |k| keys[k] << :a }
b.each_key { |k| keys[k] << :b }
c.each_key { |k| keys[k] << :c }

更确切地说,keys存储符号数组。运行上面的代码后它看起来像这样:

keys
#=> {"A"=>[:a, :b],
#    "B"=>[:a, :b],
#    "C"=>[:a],
#    "D"=>[:b, :c],
#    "E"=>[:b, :c],
#    "F"=>[:c]}

获得预期的输出:

keys.each do |key, hashes|
  next if hashes.size < 2
  hashes.each { |hash| puts "#{key} is also in #{hash}" }
end

打印:

A is also in a
A is also in b
B is also in a
B is also in b
D is also in b
D is also in c
E is also in b
E is also in c