Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
Hash#transform_keys
static VALUE
rb_hash_transform_keys(int argc, VALUE *argv, VALUE hash)
{
VALUE result;
struct transform_keys_args transarg = {0};
argc = rb_check_arity(argc, 0, 1);
if (argc > 0) {
transarg.trans = to_hash(argv[0]);
transarg.block_given = rb_block_given_p();
}
else {
RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
}
result = rb_hash_new_capa(RHASH_SIZE(hash));
if (!RHASH_EMPTY_P(hash)) {
if (transarg.trans) {
transarg.result = result;
rb_hash_foreach(hash, transform_keys_hash_i, (VALUE)&transarg);
}
else {
rb_hash_foreach(hash, transform_keys_i, result);
}
}
return result;
}
With an argument, a block, or both given, derives a new hash new_hash from self, the argument, and/or the block; all, some, or none of its keys may be different from those in self.
With a block given and no argument, new_hash has keys determined only by the block.
For each key/value pair old_key/value in self, calls the block with old_key; the block’s return value becomes new_key; sets new_hash[new_key] = value; a duplicate key overwrites:
h = {foo: 0, bar: 1, baz: 2} h.transform_keys {|old_key| old_key.to_s } # => {"foo" => 0, "bar" => 1, "baz" => 2} h.transform_keys {|old_key| 'xxx' } # => {"xxx" => 2}
With argument other_hash given and no block, new_hash may have new keys provided by other_hash and unchanged keys provided by self.
For each key/value pair old_key/old_value in self, looks for key old_key in other_hash:
-
If
old_keyis found, its valueother_hash[old_key]is taken asnew_key; setsnew_hash[new_key] = value; a duplicate key overwrites:Exampleh = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ, bar: :BAR, foo: :FOO) # => {FOO: 0, BAR: 1, BAZ: 2} h.transform_keys(baz: :FOO, bar: :FOO, foo: :FOO) # => {FOO: 2}
-
If
old_keyis not found, setsnew_hash[old_key] = value; a duplicate key overwrites:Exampleh = {foo: 0, bar: 1, baz: 2} h.transform_keys({}) # => {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :foo) # => {foo: 2, bar: 1}
Unused keys in other_hash are ignored:
h = {foo: 0, bar: 1, baz: 2} h.transform_keys(bat: 3) # => {foo: 0, bar: 1, baz: 2}
With both argument other_hash and a block given, new_hash has new keys specified by other_hash or by the block, and unchanged keys provided by self.
For each pair old_key and value in self:
-
If
other_hashhas keyold_key(with valuenew_key), does not call the block for that key; setsnew_hash[new_key] = value; a duplicate key overwrites:Exampleh = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ, bar: :BAR, foo: :FOO) {|key| fail 'Not called' } # => {FOO: 0, BAR: 1, BAZ: 2}
-
If
other_hashdoes not have keyold_key, calls the block withold_keyand takes its return value asnew_key; setsnew_hash[new_key] = value; a duplicate key overwrites:Exampleh = {foo: 0, bar: 1, baz: 2} h.transform_keys(baz: :BAZ) {|key| key.to_s.reverse } # => {"oof" => 0, "rab" => 1, BAZ: 2} h.transform_keys(baz: :BAZ) {|key| 'ook' } # => {"ook" => 1, BAZ: 2}
With no argument and no block given, returns a new Enumerator.
Related: see Methods for Transforming Keys and Values.
Ruby version changes
-
3.0
-
Hash#transform_keysandHash#transform_keys!now accept a hash that maps keys to new keys. [Feature #16274]
-