Reason #78 • March 19th, 2026

Hash#transform_values

Hash#transform_values accepts a block to transform the values of a hash while keeping the keys intact. Perfect for normalizing data or applying transformations to all values in one go.

Ruby
dodgy_event_counts = {
  sent: 5,
  delivered: 4,
  opened: nil,
  clicked: nil
}

event_counts = dodgy_event_counts.transform_values do |value|
  value || 0
end
# => { sent: 5, delivered: 4, opened: 0, clicked: 0 }

# Since NilClass#to_i is 0, we can condense further:
event_counts = dodgy_event_counts.transform_values(&:to_i)
# => { sent: 5, delivered: 4, opened: 0, clicked: 0 }
      
JavaScript
const dodgyEventCounts = {
  sent: 5,
  delivered: 4,
  opened: null,
  clicked: null
};

const normalized = Object.fromEntries(
  Object
    .entries(dodgyEventCounts)
    .map(([key, value]) => [key, value || 0])
);
// => { sent: 5, delivered: 4, opened: 0, clicked: 0 }
      

We can express this with map { ... }.to_h too, but transform_values states intent directly: keep keys, transform values. When we can leverage symbol-to-proc it's even more of a W

History

Hash#transform_values was added in Ruby 2.4 released in 2016 after having spent two years as part of ActiveSupport since Rails 4.2.

Reason #79 ?