请教如何判定以下 hash 相同。
如
{'a' => 1, 'b => 2}
与 {'a' => '1', 'b' => '2'}
{'a' => 1, 'b' => {'c' => 3}}
与 {'a' => '1', 'b' => {'c' => '3'}}
{'a' => 1, 'b' => 2} == {'a' => '1', 'b' => '2'} {'a' => 1, 'b' => {'c' => 3}} == {'a' => '1', 'b' => {'c' => '3'}}
#1 楼 @zgm
#2 楼 @fresh_fish 不好意思,我没表达清楚。我希望
{'a' => 1, 'b' => 2} == {'a' => '1', 'b' => '2'} #==> true
已修改原题
这个问题比较麻烦... 你要写一个递归的比较方法:
def compare a, b
case a
when Hash
return false unless b.is_a?(Hash) and b.size == a.size
a.sort.zip b.sort do |(ka, va), (kb, vb)|
return false unless compare(ka, kb) and compare(va, vb)
end
true
when Array
... # 类似 Hash
else
return false if b.is_a?(Hash) or b.is_a?(Array)
a.to_s == b.to_s
end
end
当然上面的代码还是有一点点问题,就是引用到父元素时会无限循环 (例如:
h = {}; h['a'] = h
), 所以还得把比较过的元素存起来验证是否已经比较过了...
def split_hash(h)
g = {}
h.each_pair do |k, v|
g[k.to_s] = v.is_a?(Hash) ? split_hash(v) : v.to_s
end
g
end
split_hash(h1) == h2
这个版本 仅仅满足你题目的需求
1.9.3-p286 :004 > a = {'a' => 1, 'b' => 2 }
=> {"a"=>1, "b"=>2}
1.9.3-p286 :005 > b = {'a' => 1, 'b' => 2 }
=> {"a"=>1, "b"=>2}
1.9.3-p286 :006 > a == b
=> true
@luikore @fresh_fish 没必要那么麻烦,通过字符串比较就可以了
a = {'a' => 1, 'b' => 2}.to_s.gsub(/"/im,'')
b = {'a' => '1', 'b' => '2'}.to_s.gsub(/"/im,'')
a == b # true
Good!
简单点,可以写作:
a = {'a' => 1, 'b' => 2}.to_s.gsub("\"", "")
b = {'a' => '1', 'b' => '2'}.to_s.gsub("\"", "")
p a == b
a = {'a' => '""1""'}.to_s.gsub(/"/im,'')
b = {'a' => '\\1\\'}.to_s.gsub(/"/im,'')
a == b # true
:(