Last active
April 2, 2023 11:56
-
-
Save okuramasafumi/406772d6737b7de1d1e693ec1a708482 to your computer and use it in GitHub Desktop.
[Proposal] Hash#transform in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Hash | |
def transform(&block) | |
new_hash = {} | |
each_pair do |key, value| | |
rtn = block.call(key, value) | |
case rtn | |
in nil | true then new_hash[key] = value | |
in false then next | |
in Array[[_, _], *] | |
rtn.each do |k, v| | |
new_hash[k] = v | |
end | |
in [k, v] then new_hash[k] = v | |
else | |
raise 'Unexpected return value' | |
end | |
end | |
new_hash | |
end | |
end | |
require 'minitest/autorun' | |
class HashTransformTest < MiniTest::Test | |
def test_transform | |
hash = {a: 1, b: 2, c: 3} | |
new_hash = hash.transform do |key, value| | |
[key.to_s, value * 2] | |
end | |
assert_equal({'a' => 2, 'b' => 4, 'c' => 6}, new_hash) | |
new_hash2 = hash.transform do |key, value| | |
[key.to_s, value * 2] if value.odd? | |
end | |
assert_equal({'a' => 2, :b => 2, 'c' => 6}, new_hash2) | |
new_hash3 = hash.transform do |key, value| | |
if value.even? | |
false | |
else | |
[key.to_s, value * 2] | |
end | |
end | |
assert_equal({'a' => 2, 'c' => 6}, new_hash3) | |
new_hash4 = hash.transform do |key, value| | |
[[key.to_s, value * 2], [key, value]] | |
end | |
assert_equal({'a' => 2, :a => 1, 'b' => 4, :b => 2, 'c' => 6, :c => 3}, new_hash4) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment