Skip to content

Instantly share code, notes, and snippets.

@okuramasafumi
Last active April 2, 2023 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okuramasafumi/406772d6737b7de1d1e693ec1a708482 to your computer and use it in GitHub Desktop.
Save okuramasafumi/406772d6737b7de1d1e693ec1a708482 to your computer and use it in GitHub Desktop.
[Proposal] Hash#transform in Ruby
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