2016-09-12 4 views
0

Чтобы упростить ситуацию, скажем, у меня есть хеши ниже.Поиск дубликатов ключей через хэши?

Я хотел бы найти ключи, которые находятся в нескольких хэшах и имя хешей. Так что в идеале я хотел бы закончить с

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 

Единственный способ, которым я могу думать: класть все ключи в массиве, сортировки, удалить уникальные элементы, поиск каждого хеш, которые содержат элементы массива remaing.

Это довольно сложно и хакки, я думаю.

Вопрос

Есть ли более простой способ найти дубликаты ключей через хэшей?

!/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 
+0

Вы пытались что-нибудь? Не могли бы вы поделиться своими усилиями? –

+0

Что такое «имя хешей»? Хэши не имеют имен в Ruby. –

ответ

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

Печать имена хэшей Tricker. See this question.

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"] 
Смежные вопросы