class HashDiff

Get diff from two hashes. (or from other data structure) return format: {:from => , :to => }

HashDiff.get_diff 1, 1 # => nil HashDiff.get_diff 1, 2 # => {:from=>1, :to=>2} HashDiff.get_diff({:a => 1, :b => 2, :c => ‘4’}, {:a => 4, :b => true, :c => 5}) do |x, y| x.is_a?(Fixnum) || y.is_a?(TrueClass) end # => {:from=>{:c=>“4”}, :to=>{:c=>5}} HashDiff.get_diff [1,2,3], # => {:from=>, :to=>} a = {:a_num=>1, :same_num=>0, :an_other_num=>3, :create=>{:user=>[“new”, “save”]}, :an_array=>[1, 2, 3], :complex_json=>{:a=>{:b=>{:c=>“d”, :f=>“x”}}}} b = {:a_num=>2, :same_num=>0, :update=>{:user=>[“edit”, “update”]}, :an_array=>[1, 2, 4], :an_other_array=>, :complex_json=>{:a=>{:b=>{:c=>“d”, :f=>“g”}, :h=>“i”}}} HashDiff.get_diff a, b # => {:from=>{:a_num=>1, :an_other_num=>3, :create=>{:user=>[“new”, “save”]}, :an_array=>, :complex_json=>{:a=>{:b=>{:f=>“x”}}}}, :to=>{:a_num=>2, :update=>{:user=>[“edit”, “update”]}, :an_array=>, :an_other_array=>, :complex_json=>{:a=>{:b=>{:f=>“g”}, :h=>“i”}}}}

Public Class Methods

get_diff(h1, h2) { |h1, h2| ... } click to toggle source
# File lib/patch_utils/hash_diff.rb, line 16
def self.get_diff h1, h2, &blk
  if block_given?
    return nil if yield(h1, h2)
  else
    return nil if h1 == h2
  end

  if h1.is_a?(Array) && h2.is_a?(Array)
    return {:from => (h1 - h2), :to => (h2 - h1)}
  end

  if h1.is_a?(Hash) && h2.is_a?(Hash)
    same_keys = (h1.keys & h2.keys)
    from = h1.clone
    to = h2.clone
    same_keys.each do |k|
      if block_given?
        if yield(h1[k], h2[k])
          from.delete(k)
          to.delete(k)
        end
      else
        if h1[k] == h2[k]
          from.delete(k)
          to.delete(k)
        end
      end
      _diff = self.get_diff(h1[k], h2[k], &blk)
      if _diff.present?
        from[k] = _diff[:from]
        to[k] = _diff[:to]
      end
    end
    return {:from => from, :to => to}
  end
  {:from => h1, :to => h2}
end