diff options
author | Guillermo Iguaran <guilleiguaran@gmail.com> | 2019-02-08 12:28:12 -0500 |
---|---|---|
committer | Guillermo Iguaran <guilleiguaran@gmail.com> | 2019-02-08 12:28:38 -0500 |
commit | b8dc06b8fdc16874160f61dcf58743fcc10e57db (patch) | |
tree | 4dd55334bdc2c7a30073f5b52b7a3cc4a5e3c94d /activesupport/lib | |
parent | 5f9e05048d409b9c3fb35a3620fe361fb03dd4e1 (diff) | |
download | rails-b8dc06b8fdc16874160f61dcf58743fcc10e57db.tar.gz rails-b8dc06b8fdc16874160f61dcf58743fcc10e57db.tar.bz2 rails-b8dc06b8fdc16874160f61dcf58743fcc10e57db.zip |
Add 'Hash#deep_transform_values', and 'Hash#deep_transform_values!'
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash.rb | 1 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb | 52 |
2 files changed, 53 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash.rb b/activesupport/lib/active_support/core_ext/hash.rb index c4b9e5f1a0..2f0901d853 100644 --- a/activesupport/lib/active_support/core_ext/hash.rb +++ b/activesupport/lib/active_support/core_ext/hash.rb @@ -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" diff --git a/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb new file mode 100644 index 0000000000..ab68c34309 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb @@ -0,0 +1,52 @@ +# 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 |