Ruby 2.4 Hash#transform_values & destructive version

Sushant Mittal

By Sushant Mittal

on June 14, 2017

This blog is part of our  Ruby 2.4 series.

It is a common use case to transform the values of a hash.

1
2{ a: 1, b: 2, c: 3 } => { a: 2, b: 4, c: 6 }
3
4{ a: "B", c: "D", e: "F" } => { a: "b", c: "d", e: "f" }
5

We can transform the values of a hash destructively (i.e. modify the original hash with new values) or non-destructively (i.e. return a new hash instead of modifying the original hash).

Prior to Ruby 2.4, we need to use following code to transform the values of a hash.

1
2# Ruby 2.3 Non-destructive version
3
4> hash = { a: 1, b: 2, c: 3 }
5 #=> {:a=>1, :b=>2, :c=>3}
6
7> hash.inject({}) { |h, (k, v)| h[k] = v * 2; h }
8 #=> {:a=>2, :b=>4, :c=>6}
9
10> hash
11 #=> {:a=>1, :b=>2, :c=>3}
12
13> hash = { a: "B", c: "D", e: "F" }
14 #=> {:a=>"B", :c=>"D", :e=>"F"}
15
16> hash.inject({}) { |h, (k, v)| h[k] = v.downcase; h }
17 #=> {:a=>"b", :c=>"d", :e=>"f"}
18
19> hash
20 #=> {:a=>"B", :c=>"D", :e=>"F"}
21
1
2# Ruby 2.3 Destructive version
3
4> hash = { a: 1, b: 2, c: 3 }
5 #=> {:a=>1, :b=>2, :c=>3}
6
7> hash.each { |k, v| hash[k] = v * 2 }
8 #=> {:a=>2, :b=>4, :c=>6}
9
10> hash
11 #=> {:a=>2, :b=>4, :c=>6}
12
13> hash = { a: "B", c: "D", e: "F" }
14 #=> {:a=>"B", :c=>"D", :e=>"F"}
15
16> hash.each { |k, v| hash[k] = v.downcase }
17 #=> {:a=>"b", :c=>"d", :e=>"f"}
18
19> hash
20 #=> {:a=>"b", :c=>"d", :e=>"f"}
21

transform_values and transform_values! from Active Support

Active Support has already implemented handy methods Hash#transform_values and Hash#transform_values! to transform hash values.

Now, Ruby 2.4 has also implemented Hash#map_v and Hash#map_v! and then renamed to Hash#transform_values and Hash#transform_values! for the same purpose.

1
2# Ruby 2.4 Non-destructive version
3
4> hash = { a: 1, b: 2, c: 3 }
5 #=> {:a=>1, :b=>2, :c=>3}
6
7> hash.transform_values { |v| v * 2 }
8 #=> {:a=>2, :b=>4, :c=>6}
9
10> hash
11 #=> {:a=>1, :b=>2, :c=>3}
12
13> hash = { a: "B", c: "D", e: "F" }
14 #=> {:a=>"B", :c=>"D", :e=>"F"}
15
16> hash.transform_values(&:downcase)
17 #=> {:a=>"b", :c=>"d", :e=>"f"}
18
19> hash
20 #=> {:a=>"B", :c=>"D", :e=>"F"}
21
1
2# Ruby 2.4 Destructive version
3
4> hash = { a: 1, b: 2, c: 3 }
5 #=> {:a=>1, :b=>2, :c=>3}
6
7> hash.transform_values! { |v| v * 2 }
8 #=> {:a=>2, :b=>4, :c=>6}
9
10> hash
11 #=> {:a=>2, :b=>4, :c=>6}
12
13> hash = { a: "B", c: "D", e: "F" }
14 #=> {:a=>"B", :c=>"D", :e=>"F"}
15
16> hash.transform_values!(&:downcase)
17 #=> {:a=>"b", :c=>"d", :e=>"f"}
18
19> hash
20 #=> {:a=>"b", :c=>"d", :e=>"f"}
21

If you liked this blog, you might also like the other blogs we have written. Check out the full archive.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, React.js, React Native, remote work,open source, engineering & design.