diff --git a/spec/std/hash_spec.cr b/spec/std/hash_spec.cr index bede7ce15687..73f3ef53d632 100644 --- a/spec/std/hash_spec.cr +++ b/spec/std/hash_spec.cr @@ -923,6 +923,36 @@ describe "Hash" do h2.should eq({"1a" => "a", "2b" => "b", "3c" => "c"}) end + describe "transform_keys!" do + it "transforms keys in place" do + h = {1 => "a", 2 => "b", 3 => "c"} + + h.transform_keys! { |x| x + 1 }.should be(h) + h.should eq({2 => "a", 3 => "b", 4 => "c"}) + end + + it "does nothing when empty hash" do + h = {} of Int32 => String + + h.transform_keys! { |x| x + 1 } + h.should be_empty + end + + it "transforms keys with values included" do + h = {"1" => "a", "2" => "b", "3" => "c"} + + h.transform_keys! { |k, v| "#{k}#{v}" } + h.should eq({"1a" => "a", "2b" => "b", "3c" => "c"}) + end + + it "allows transformed key type to be a subtype of the original type" do + h = {"1" => "foo", 2 => "bar"} # Hash(Int32 | String, String) + + h.transform_keys!(&.to_i) + h.should eq({1 => "foo", 2 => "bar"}) + end + end + it "transforms values" do h1 = {"a" => 1, "b" => 2, "c" => 3} diff --git a/src/hash.cr b/src/hash.cr index 1b6c1b2308dd..387078fb660e 100644 --- a/src/hash.cr +++ b/src/hash.cr @@ -1755,6 +1755,24 @@ class Hash(K, V) end end + # Destructively transforms all keys using a block. Same as transform_keys but modifies in place. + # The block cannot change a type of keys. + # The block yields the key and value. + # + # ``` + # hash = {"a" => 1, "b" => 2, "c" => 3} + # hash.transform_keys! { |key| key.upcase } + # hash # => {"A" => 1, "B" => 2, "C" => 3} + # hash.transform_keys! { |key, value| key * value } + # hash # => {"a" => 1, "bb" => 2, "ccc" => 3} + # ``` + def transform_keys!(&block : K, V -> K) : self + transformed_hash = self.transform_keys(&block) + initialize_dup_entries(transformed_hash) # we need only to copy the buffer + initialize_copy_non_entries_vars(transformed_hash) + self + end + # Returns a new hash with the results of running block once for every value. # The block can change a type of values. # The block yields the value and key.