Last active
December 21, 2015 07:48
-
-
Save alenia/6273654 to your computer and use it in GitHub Desktop.
Add deep_diff method to Hash to more easily see locations of differences between crazy nested hashes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DiffObject | |
attr :left, :right | |
def initialize(left, right) | |
@left = left | |
@right = right | |
end | |
end | |
class Hash | |
# a_hash.deep_diff(b_hash) returns: | |
# key_with_different_value => DiffObject, key_with_hash_value_in_both => {nested_key_with_different_value => DiffObject} | |
def deep_diff(other_hash) | |
diff = {} | |
keys.each do |key| | |
if (value = self[key]) == (other_value = other_hash[key]) | |
next | |
elsif (value.is_a?(Hash) && other_value.is_a?(Hash)) || (value.is_a?(Array) && other_value.is_a?(Array)) | |
diff[key] = value.deep_diff(other_value) | |
else | |
diff[key] = DiffObject.new(value, other_value) | |
end | |
end | |
(other_hash.keys - keys).each do |key| | |
diff[key] = DiffObject.new(nil, other_hash[key]) | |
end | |
diff | |
end | |
end | |
class Array | |
#not really good about ordering | |
def deep_diff(other_array) | |
if self.length != other_array.length | |
DiffObject.new(self, other_array) | |
elsif (self.all?{|v| v.is_a?(Hash)} && other_array.all?{|v| v.is_a?(Hash)}) || (self.all?{|v| v.is_a?(Array)} && other_array.all?{|v| v.is_a?(Array)}) | |
self.each_with_index.map{|value,i| value.deep_diff(other_array[i])} | |
else | |
DiffObject.new(self, other_array) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment