Найти (глубокое) дополнение двух хешей - PullRequest
1 голос
/ 10 марта 2012

дополнение - это математический термин для того, что я ищу, но для контекста и, возможно, более целевого решения: у меня есть хэш A, который может иметь вложенные хэши (т.е. они являются N-мерными ), и я применяю к нему процесс (над которым у меня нет контроля), который возвращает хеш B, который является хешем A с некоторыми удаленными элементами. С этого момента я пытаюсь найти элементы в A, которые были удалены из B.

Например: (обратите внимание, что я использую символы для простоты. Ключи всегда будут символами, но значения не будут.)

a = {:a => :b,
     :c => {:d => :e, :f => :g},
     :h => :i,
     :j => {:k => :l, :m => :n},
     :o => {:p => :q, :r => :s},
     :t => :u}

b = {:h => :i,
     :j => {:k => :l, :m => :n},
     :o => {:r => :s},
     :t => :u}

complement(a,b)
#=> {:a => :b,
#    :c => {:d => :e, :f => :g},
#    :o => {:p => :q}}

Каков наилучший (рубиновый) способ сделать это?

1 Ответ

1 голос
/ 10 марта 2012

Придумали это

a = {a: "thing", b: [1,2,3], c:2}
b = {a: "thing", b: [1,2,3]}
c= {}
a.each do |k, v|
  c[k] = v unless b[k]
end
p c

РЕДАКТИРОВАТЬ: Теперь проверка вложенных хэшей.Но да, должен быть какой-то лучший рубиновый способ сделать это.

def check_deleted(a, b)
    c = Hash.new
    a.each do |k, v|
        if ! b.has_key? k
            c[k] = v
        elsif b[k].is_a? Hash
            c[k] = check_deleted(v, b[k])
        end
    end
    c
end
a = {a: "thing", b: [1,2,3], c:2, d: {e: 1, r:2}}
b = {a: "thing", b: [1,2,3], d: {r:2}}

p check_deleted(a,b) #=> {:c=>2, :d=>{:e=>1}}
...