Back to Blog

Ruby 2.4 Hash#transform_values & destructive version

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

You might also like

If you liked this blog post, check out similar ones from BigBinary