2012-03-10 28 views
1

complement是我正在寻找的数学术语,但对于上下文和可能更有针对性的解决方案:我有散列A,它可以嵌套散列(即它们是N维),并且我向它应用了一个返回散列B的过程(在这个过程中,我无法控制),散列B是散列A,其中一些元素被删除。从那里开始,我试图找到A中已经被删除的元素。查找两个哈希的(深)补码

例如:(注意,为了简单起见,我使用了符号,键将始终是符号,但值不会。)

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

什么是最好的(ruby-esque)这样做的方式?

+0

深度是否随意?数组中是否存在潜在的重复元素?你在乎*这些元素在哪里?或者只是它们被删除了? – 2012-03-10 02:26:04

+0

深度是任意的(这是用户输入),尽管它不应超过两个或三个级别。至于重复,这是我们正在讨论的哈希,所以键*不能*有重复;价值可以,当然。最后,我检查了一下,哈希没有排序。 – 2012-03-10 02:30:08

+0

哈希按广告顺序按1.9排序,但未在1.8中指定顺序。 – 2012-03-10 02:34:29

回答

1

想出了这个

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}} 
+0

是的,这只适用于一维哈希。 – 2012-03-10 02:32:41

+0

哦,我忘了那个。 – 2012-03-10 02:36:28

+0

这有效......如果没有人来,并且给出一个ruby-esque-er解决方案,我会接受它:) – 2012-03-10 03:04:11