diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-05-20 21:49:58 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-05-20 21:49:58 -0300 |
commit | decd71971178fc82c6442a207b79fa2462bdfc8d (patch) | |
tree | d08f18420e4edd27c4acefba3f4c273eb66ea6b7 /activesupport/lib/active_support | |
parent | 9a1abedcdeecd9464668695d4f9c1d55a2fd9332 (diff) | |
parent | ac0b1d835d183cb117adb8d61307b8f40e9b1440 (diff) | |
download | rails-decd71971178fc82c6442a207b79fa2462bdfc8d.tar.gz rails-decd71971178fc82c6442a207b79fa2462bdfc8d.tar.bz2 rails-decd71971178fc82c6442a207b79fa2462bdfc8d.zip |
Merge pull request #10887 from sakuro/deep_transform_keys_in_nested_arrays
Hash#deep_*_keys(!) recurse into nested arrays.
Conflicts:
activesupport/CHANGELOG.md
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/keys.rb | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb index 3d41aa8572..28536e32a4 100644 --- a/activesupport/lib/active_support/core_ext/hash/keys.rb +++ b/activesupport/lib/active_support/core_ext/hash/keys.rb @@ -75,34 +75,26 @@ 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. + # nested hashes and arrays. # # hash = { person: { name: 'Rob', age: '28' } } # # hash.deep_transform_keys{ |key| key.to_s.upcase } # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}} def deep_transform_keys(&block) - result = {} - each do |key, value| - result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value - end - result + _deep_transform_keys_in_object(self, &block) end # Destructively convert all keys by using the block operation. # This includes the keys from the root hash and from all - # nested hashes. + # nested hashes and arrays. def deep_transform_keys!(&block) - keys.each do |key| - value = delete(key) - self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value - end - self + _deep_transform_keys_in_object!(self, &block) end # Returns a new hash with all keys converted to strings. # This includes the keys from the root hash and from all - # nested hashes. + # nested hashes and arrays. # # hash = { person: { name: 'Rob', age: '28' } } # @@ -114,14 +106,14 @@ class Hash # Destructively convert all keys to strings. # This includes the keys from the root hash and from all - # nested hashes. + # nested hashes and arrays. def deep_stringify_keys! deep_transform_keys!{ |key| key.to_s } end # Returns a new hash with all keys converted to symbols, as long as # they respond to +to_sym+. This includes the keys from the root hash - # and from all nested hashes. + # and from all nested hashes and arrays. # # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } # @@ -133,8 +125,38 @@ class Hash # Destructively convert all keys to symbols, as long as they respond # to +to_sym+. This includes the keys from the root hash and from all - # nested hashes. + # nested hashes and arrays. def deep_symbolize_keys! deep_transform_keys!{ |key| key.to_sym rescue key } end + + private + # support methods for deep transforming nested hashes and arrays + def _deep_transform_keys_in_object(object, &block) + case object + when Hash + object.each_with_object({}) do |(key, value), result| + result[yield(key)] = _deep_transform_keys_in_object(value, &block) + end + when Array + object.map {|e| _deep_transform_keys_in_object(e, &block) } + else + object + end + end + + def _deep_transform_keys_in_object!(object, &block) + case object + when Hash + object.keys.each do |key| + value = object.delete(key) + object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + end + object + when Array + object.map! {|e| _deep_transform_keys_in_object!(e, &block)} + else + object + end + end end |