Created
April 10, 2025 16:23
-
-
Save blasterpal/beb3978b963dbbf295f0a3f2f7f4df72 to your computer and use it in GitHub Desktop.
Diff/Compare two Hashes
This file contains hidden or 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
def compare_hashes(hash1, hash2, options = {}) | |
options = { | |
sort_keys: true, | |
include_identical: false | |
}.merge(options) | |
# Get all keys from both hashes | |
all_keys = options[:sort_keys] ? (hash1.keys | hash2.keys).sort : (hash1.keys | hash2.keys) | |
differences = {} | |
all_keys.each do |key| | |
# Skip if key doesn't exist in either hash | |
next if !hash1.key?(key) && !hash2.key?(key) | |
# Handle missing keys | |
if !hash1.key?(key) | |
differences[key] = { only_in_second: hash2[key] } | |
next | |
elsif !hash2.key?(key) | |
differences[key] = { only_in_first: hash1[key] } | |
next | |
end | |
# Check values | |
if hash1[key] != hash2[key] | |
# Special handling for arrays | |
if hash1[key].is_a?(Array) && hash2[key].is_a?(Array) | |
array_diff = compare_arrays(hash1[key], hash2[key]) | |
differences[key] = array_diff unless array_diff.empty? | |
# Special handling for nested hashes | |
elsif hash1[key].is_a?(Hash) && hash2[key].is_a?(Hash) | |
nested_diff = compare_hashes(hash1[key], hash2[key], options) | |
differences[key] = nested_diff unless nested_diff.empty? | |
else | |
differences[key] = { | |
first: hash1[key], | |
second: hash2[key] | |
} | |
end | |
elsif options[:include_identical] | |
differences[key] = { | |
identical: true, | |
value: hash1[key] | |
} | |
end | |
end | |
differences | |
end | |
# Thanks Claude | |
def compare_arrays(array1, array2) | |
result = {} | |
# Items in first but not second | |
only_in_first = array1 - array2 | |
result[:only_in_first] = only_in_first unless only_in_first.empty? | |
# Items in second but not first | |
only_in_second = array2 - array1 | |
result[:only_in_second] = only_in_second unless only_in_second.empty? | |
# Items in both (if needed) | |
in_both = array1 & array2 | |
result[:in_both] = in_both unless in_both.empty? | |
result | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment