提交 b8dc06b8 编写于 作者: G Guillermo Iguaran

Add 'Hash#deep_transform_values', and 'Hash#deep_transform_values!'

上级 5f9e0504
......@@ -12,6 +12,10 @@
*Stefan Schüßler*
* Add `Hash#deep_transform_values`, and `Hash#deep_transform_values!`.
*Guillermo Iguaran*
## Rails 6.0.0.beta1 (January 18, 2019) ##
* Remove deprecated `Module#reachable?` method.
......
......@@ -2,6 +2,7 @@
require "active_support/core_ext/hash/conversions"
require "active_support/core_ext/hash/deep_merge"
require "active_support/core_ext/hash/deep_transform_values"
require "active_support/core_ext/hash/except"
require "active_support/core_ext/hash/indifferent_access"
require "active_support/core_ext/hash/keys"
......
# frozen_string_literal: true
class Hash
# Returns a new hash with all keys converted by the block operation.
# This includes the keys from the root hash and from all
# nested hashes and arrays.
#
# hash = { person: { name: 'Rob', age: '28' } }
#
# hash.deep_transform_values{ |value| value.to_s.upcase }
# # => {person: {name: "ROB", age: "28"}}
def deep_transform_values(&block)
_deep_transform_values_in_object(self, &block)
end
# Destructively converts all values by using the block operation.
# This includes the values from the root hash and from all
# nested hashes and arrays.
def deep_transform_values!(&block)
_deep_transform_values_in_object!(self, &block)
end
private
# support methods for deep transforming nested hashes and arrays
def _deep_transform_values_in_object(object, &block)
case object
when Hash
object.each_with_object({}) do |(key, value), result|
result[key] = _deep_transform_values_in_object(value, &block)
end
when Array
object.map { |e| _deep_transform_values_in_object(e, &block) }
else
yield(object)
end
end
def _deep_transform_values_in_object!(object, &block)
case object
when Hash
object.keys.each do |key|
value = object.delete(key)
object[key] = _deep_transform_values_in_object!(value, &block)
end
object
when Array
object.map! { |e| _deep_transform_values_in_object!(e, &block) }
else
yield(object)
end
end
end
......@@ -33,6 +33,8 @@ def test_methods
h = {}
assert_respond_to h, :deep_transform_keys
assert_respond_to h, :deep_transform_keys!
assert_respond_to h, :deep_transform_values
assert_respond_to h, :deep_transform_values!
assert_respond_to h, :symbolize_keys
assert_respond_to h, :symbolize_keys!
assert_respond_to h, :deep_symbolize_keys
......@@ -78,6 +80,31 @@ def test_deep_transform_keys_with_bang_mutates
assert_equal({ "a" => { b: { "c" => 3 } } }, @nested_mixed)
end
def test_deep_transform_values
assert_equal({ "a" => "1", "b" => "2" }, @strings.deep_transform_values{ |value| value.to_s })
assert_equal({ "a" => { "b" => { "c" => "3" } } }, @nested_strings.deep_transform_values { |value| value.to_s })
assert_equal({ "a" => [ { "b" => "2" }, { "c" => "3" }, "4" ] }, @string_array_of_hashes.deep_transform_values { |value| value.to_s })
end
def test_deep_transform_values_not_mutates
transformed_hash = @nested_mixed.deep_dup
transformed_hash.deep_transform_values { |value| value.to_s }
assert_equal @nested_mixed, transformed_hash
end
def test_deep_transform_values!
assert_equal({ "a" => "1", "b" => "2" }, @strings.deep_transform_values!{ |value| value.to_s })
assert_equal({ "a" => { "b" => { "c" => "3" } } }, @nested_strings.deep_transform_values! { |value| value.to_s })
assert_equal({ "a" => [ { "b" => "2" }, { "c" => "3" }, "4" ] }, @string_array_of_hashes.deep_transform_values! { |value| value.to_s })
end
def test_deep_transform_values_with_bang_mutates
transformed_hash = @nested_mixed.deep_dup
transformed_hash.deep_transform_values! { |value| value.to_s }
assert_equal({ "a" => { b: { "c" => "3" } } }, transformed_hash)
assert_equal({ "a" => { b: { "c" => 3 } } }, @nested_mixed)
end
def test_symbolize_keys
assert_equal @symbols, @symbols.symbolize_keys
assert_equal @symbols, @strings.symbolize_keys
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册