Hash#transform_keys
hash.transform_keys { |key| block } -> hash Hash · Added in v2.5 · Updated March 16, 2026 · Hash Methods Hash#transform_keys creates a new hash by transforming each key using a block. Unlike Hash#each_with_object or manual iteration, this method provides a focused way to remap keys while keeping values intact.
Syntax
hash.transform_keys { |key| block }
The block receives each key and should return the new key to use.
Basic Usage
Simple key transformation
user = { name: "Alice", age: 30, city: "London" }
user.transform_keys { |key| key.to_s.upcase }
# => { "NAME" => "Alice", "AGE" => 30, "CITY" => "London" }
Symbol to string keys
config = { debug: true, timeout: 30, max_retries: 5 }
config.transform_keys(&:to_s)
# => { "debug" => true, "timeout" => 30, "max_retries" => 5 }
String to symbol keys
data = { "name" => "Bob", "age" => 25 }
data.transform_keys(&:to_sym)
# => { name: "Bob", age: 25 }
Transforming with Custom Logic
Prefix or suffix keys
env = { DB_HOST: "localhost", DB_PORT: 5432 }
env.transform_keys { |k| "APP_#{k}" }
# => { "APP_DB_HOST" => "localhost", "APP_DB_PORT" => 5432 }
Convert snake_case to camelCase
params = { user_name: "alice", user_email: "alice@example.com" }
params.transform_keys { |k| k.to_s.gsub(/_([a-z])/) { $1.upcase } }
# => { userName: "alice", userEmail: "alice@example.com" }
Flatten nested keys
nested = { "user.name" => "Alice", "user.age" => 30 }
nested.transform_keys { |k| k.split(".") }
# => { ["user", "name"] => "Alice", ["user", "age"] => 30 }
Comparison with Related Methods
transform_keys vs map
Using transform_keys is more idiomatic than using map to transform keys:
hash = { a: 1, b: 2 }
# Less idiomatic
hash.map { |k, v| [k.to_s, v] }.to_h
# => { "a" => 1, "b" => 2 }
# More idiomatic
hash.transform_keys(&:to_s)
# => { "a" => 1, "b" => 2 }
transform_keys vs transform_keys!
The bang version transform_keys! modifies the hash in place:
config = { debug: true, verbose: false }
config.transform_keys!(&:to_s)
# config is now { "debug" => true, "verbose" => false }
Use transform_keys when you want an immutable operation (returning a new hash).
transform_keys vs transform_values
Transform keys operates on keys while keeping values the same:
scores = { alice: 95, bob: 82, carol: 78 }
scores.transform_keys(&:to_s)
# => { "alice" => 95, "bob" => 82, "carol" => 78 }
For transforming values instead, use transform_values:
scores.transform_values { |v| v + 10 }
# => { alice: 105, bob: 92, carol: 88 }
Chaining with Other Methods
Combine with select
data = { name: "Alice", age: 30, email: "alice@example.com", city: "London" }
data
.transform_keys(&:to_s)
.select { |k, _| k.start_with?("name", "email") }
# => { "name" => "Alice", "email" => "alice@example.com" }
Combine with transform_values
prices = { apple: 100, banana: 200, orange: 150 }
prices
.transform_keys(&:to_s)
.transform_values { |v| v * 1.1.round(2) }
# => { "apple" => 110.0, "banana" => 220.0, "orange" => 165.0 }
Combine with merge
defaults = { debug: false, timeout: 30 }
defaults.transform_keys(&:to_s).merge({ "debug" => true })
# => { "debug" => true, "timeout" => 30 }
In-Place Modification with transform_keys!
If you need to modify the original hash rather than creating a new one, use transform_keys!:
settings = { env: "production", log_level: "info" }
settings.transform_keys!(&:to_s)
# settings is now { "env" => "production", "log_level" => "info" }
This is useful when working with configuration objects that you want to modify directly.
Edge Cases
Empty hash
{}.transform_keys { |k| k.to_s }
# => {}
Duplicate transformed keys
When multiple keys transform to the same value, the last one wins:
hash = { a: 1, b: 2 }
hash.transform_keys { |k| :same_key }
# => { same_key: 2 }
This behavior matches how Ruby handles duplicate hash keys.
Block not provided
Without a block, transform_keys returns an enumerator:
hash = { a: 1, b: 2 }
hash.transform_keys.map { |k| k.to_s }
# => ["a", "b"]
Ruby Version Notes
- Ruby 2.5: Introduced
transform_keys - Ruby 2.5: Introduced
transform_keys! - Ruby 2.5: Added blockless form returning enumerator
See Also
- Hash#values — Get all hash values as an array
- Hash#keys — Get all keys as an array
- Hash#merge — Merge hashes together