/ Tags: RUBY-CODE / Categories: SOLUTIONS

Diff Two Hashes And Return Added Removed And Changed Keys In Ruby

When comparing configuration objects, API responses, or form submissions, you often need to know exactly what changed — not just whether the hashes are equal.

Description

This method produces a structured diff between two hashes, categorizing each key difference as added (exists only in new hash), removed (exists only in old hash), or changed (exists in both but values differ). It uses Ruby’s set operations on hash keys to efficiently identify each category in a single pass. This is especially useful for audit logging, change detection in background jobs, or surfacing what changed inside before/after model callbacks.

Sample input:

  old = { name: "Alice", role: "user", age: 30 }
  new_data = { name: "Alice", role: "admin", city: "NYC" }


Sample Output:

  {
    added:   { city: "NYC" },
    removed: { age: 30 },
    changed: { role: ["user", "admin"] }
  }

Answer

  def hash_diff(old_hash, new_hash)
    old_keys = old_hash.keys.to_set
    new_keys = new_hash.keys.to_set

    {
      added:   new_hash.slice(*(new_keys - old_keys)),
      removed: old_hash.slice(*(old_keys - new_keys)),
      changed: (old_keys & new_keys).each_with_object({}) do |k, diff|
        diff[k] = [old_hash[k], new_hash[k]] if old_hash[k] != new_hash[k]
      end
    }
  end

Learn More

cdrrazan

Rajan Bhattarai

Full Stack Software Developer! 💻 🏡 Grad. Student, MCS. 🎓 Class of '23. GitKraken Ambassador 🇳🇵 2021/22. Works with Ruby / Rails. Photography when no coding. Also tweets a lot at TW / @cdrrazan!

Read More