darthjee-core_ext 1.7.4 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.circleci/config.yml +63 -9
- data/.gitignore +2 -0
- data/.reek.yml +3 -0
- data/.rubocop.yml +18 -1
- data/.rubocop_todo.yml +15 -8
- data/ARRAY_README.md +72 -15
- data/CLASS_README.md +154 -0
- data/DATE_README.md +19 -9
- data/Dockerfile +18 -5
- data/ENUMERABLE_README.md +154 -4
- data/Gemfile +13 -0
- data/HASH_README.md +276 -135
- data/MATH_README.md +14 -10
- data/Makefile +7 -0
- data/OBJECT_README.md +18 -35
- data/README.md +12 -4
- data/Rakefile +1 -0
- data/SYMBOL_README.md +13 -18
- data/config/check_specs.yml +20 -0
- data/config/rubycritc.rb +12 -0
- data/config/yardstick.yml +45 -3
- data/core_ext.gemspec +10 -18
- data/docker-compose.yml +24 -7
- data/lib/darthjee/core_ext/array/hash_builder.rb +22 -5
- data/lib/darthjee/core_ext/array.rb +22 -14
- data/lib/darthjee/core_ext/class.rb +29 -10
- data/lib/darthjee/core_ext/date.rb +1 -0
- data/lib/darthjee/core_ext/enumerable.rb +67 -29
- data/lib/darthjee/core_ext/hash/cameliazable.rb +52 -21
- data/lib/darthjee/core_ext/hash/chain_fetcher.rb +18 -1
- data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
- data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
- data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -62
- data/lib/darthjee/core_ext/hash/key_changeable.rb +138 -66
- data/lib/darthjee/core_ext/hash/key_changer.rb +146 -45
- data/lib/darthjee/core_ext/hash/keys_sorter.rb +43 -6
- data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
- data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
- data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
- data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
- data/lib/darthjee/core_ext/hash.rb +6 -4
- data/lib/darthjee/core_ext/math.rb +37 -6
- data/lib/darthjee/core_ext/numeric.rb +13 -2
- data/lib/darthjee/core_ext/object.rb +27 -0
- data/lib/darthjee/core_ext/symbol.rb +22 -2
- data/lib/darthjee/core_ext/version.rb +1 -1
- data/scripts/check_readme.sh +6 -0
- data/scripts/rubycritic.sh +10 -0
- data/spec/integration/readme/array_spec.rb +96 -0
- data/spec/integration/readme/class_spec.rb +123 -0
- data/spec/integration/readme/date_spec.rb +20 -0
- data/spec/integration/readme/enumerable_spec.rb +87 -0
- data/spec/integration/readme/hash_spec.rb +400 -0
- data/spec/integration/readme/math_spec.rb +31 -0
- data/spec/integration/readme/object_spec.rb +49 -0
- data/spec/integration/readme/symbol_spec.rb +29 -0
- data/spec/integration/yard/darthjee/core_ext/array_spec.rb +1 -1
- data/spec/integration/yard/darthjee/core_ext/class/default_value_spec.rb +10 -8
- data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
- data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
- data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
- data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
- data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +67 -37
- data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
- data/spec/integration/yard/darthjee/core_ext/hash/value_changer_spec.rb +1 -1
- data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
- data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
- data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
- data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
- data/spec/lib/array_spec.rb +2 -1
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
- data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
- data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
- data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +5 -13
- data/spec/lib/hash_spec.rb +87 -147
- data/spec/lib/object_spec.rb +32 -0
- data/spec/lib/symbol_spec.rb +2 -2
- data/spec/spec_helper.rb +4 -2
- data/spec/support/models/client.rb +23 -0
- data/spec/support/models/dummy_iterator.rb +4 -4
- data/spec/support/models/hash/value_changer/dummy.rb +1 -0
- data/spec/support/shared_examples/array/array_random.rb +2 -3
- data/spec/support/shared_examples/hash/chain_hash_keys_changer.rb +1 -1
- data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
- data/spec/support/shared_examples/hash/hash_keys_changer.rb +3 -3
- data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
- data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
- data/spec/support/shared_examples/hash/map_to_hash.rb +1 -1
- data/spec/support/shared_examples/hash/remap.rb +4 -4
- data/spec/support/shared_examples/hash/value_changer.rb +2 -2
- metadata +41 -189
- data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
- data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +0 -11
@@ -7,14 +7,26 @@ module Darthjee
|
|
7
7
|
# changing / transforming keys of a Hash
|
8
8
|
#
|
9
9
|
# @api public
|
10
|
+
#
|
11
|
+
# @author Darthjee
|
12
|
+
#
|
13
|
+
# @see KeyChanger
|
14
|
+
# @see KeysSorter
|
10
15
|
module KeyChangeable
|
11
|
-
|
12
|
-
#
|
16
|
+
##########################################
|
17
|
+
# Key change methods
|
18
|
+
##########################################
|
19
|
+
|
20
|
+
# Change all keys without changing the original hash
|
21
|
+
#
|
22
|
+
# It changes all keysby publically sending methods
|
23
|
+
# to the keys
|
13
24
|
#
|
14
25
|
# @return [::Hash] New hash with the resulting keys
|
15
|
-
# @param [::Array<Symbol>] calls methods to be
|
26
|
+
# @param [::Array<Symbol>] calls methods to be
|
27
|
+
# called form the key`
|
16
28
|
#
|
17
|
-
# @see #
|
29
|
+
# @see #chain_change_keys!
|
18
30
|
#
|
19
31
|
# @example
|
20
32
|
# hash = { first: 1, second: 2 }
|
@@ -24,20 +36,22 @@ module Darthjee
|
|
24
36
|
deep_dup.chain_change_keys!(*calls)
|
25
37
|
end
|
26
38
|
|
27
|
-
# Change all keys
|
28
|
-
#
|
39
|
+
# Change all keys changing the original hash
|
40
|
+
#
|
41
|
+
# It changes all keys by publically sending methods
|
42
|
+
# to the keys
|
29
43
|
#
|
30
44
|
# @return [::Hash] New hash with the resulting keys
|
31
45
|
# @param [::Array<Symbol>] calls methods to be called form the key`
|
32
46
|
#
|
33
|
-
# @see #
|
47
|
+
# @see #change_keys
|
34
48
|
#
|
35
49
|
# @example (see #chain_change_keys)
|
36
50
|
def chain_change_keys!(*calls)
|
37
51
|
options = calls.extract_options!
|
38
52
|
|
39
53
|
calls.inject(self) do |h, m|
|
40
|
-
h.change_keys!(options, &m)
|
54
|
+
h.change_keys!(**options, &m)
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
@@ -45,10 +59,13 @@ module Darthjee
|
|
45
59
|
#
|
46
60
|
# @return new Hash with modified keys
|
47
61
|
# @param [::Hash] options options to passed to KeyChanger
|
48
|
-
# @option options [
|
62
|
+
# @option options [::TrueClass,::FalseClass]
|
63
|
+
# recursive (true) flag defining the
|
49
64
|
# change to happen also
|
50
65
|
# on inner hashes (defaults to: true)
|
51
66
|
#
|
67
|
+
# @yield (key) changing key block
|
68
|
+
#
|
52
69
|
# @see Hash::KeyChanger#change_keys
|
53
70
|
#
|
54
71
|
# @example
|
@@ -63,78 +80,116 @@ module Darthjee
|
|
63
80
|
# (k.to_i + 1).to_s.to_sym
|
64
81
|
# end
|
65
82
|
# result # returns { :'2' => 1, :'3' => { '3' => 2 } }
|
66
|
-
def change_keys(
|
67
|
-
deep_dup.change_keys!(
|
83
|
+
def change_keys(**, &)
|
84
|
+
deep_dup.change_keys!(**, &)
|
68
85
|
end
|
69
86
|
|
70
87
|
# Change all keys modifying and returning the hash
|
71
88
|
#
|
72
89
|
# @return self
|
73
90
|
# @param [::Hash] options options to passed to KeyChanger
|
74
|
-
# @option options [
|
91
|
+
# @option options [::TrueClass,::FalseClass]
|
92
|
+
# recursive: (true) flag defining the
|
75
93
|
# change to happen also
|
76
94
|
# on inner hashes (defaults to: true)
|
77
95
|
#
|
96
|
+
# @yield (key) changing key block
|
97
|
+
#
|
78
98
|
# @see Hash::KeyChanger#change_keys
|
79
99
|
#
|
80
100
|
# @example (see #change_keys)
|
81
|
-
def change_keys!(
|
82
|
-
Hash::KeyChanger.new(self).change_keys(
|
101
|
+
def change_keys!(**, &)
|
102
|
+
Hash::KeyChanger.new(self).change_keys(**, &)
|
83
103
|
end
|
84
104
|
|
85
105
|
# prepend a string to all keys
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
|
93
|
-
|
106
|
+
#
|
107
|
+
# @param options [::Hash]
|
108
|
+
# @option options [::TrueClass,::FalseClass]
|
109
|
+
# recursive (true)
|
110
|
+
# flag indicating transformation should be recursive
|
111
|
+
# @option options [::Symbol] type (:keep)
|
112
|
+
# type of the final key
|
113
|
+
# - keep : cast the result to the same type of the
|
114
|
+
# original key
|
115
|
+
# - string : cast the result to be {::String}
|
116
|
+
# - symbol cast the result to be {::Symbol}
|
117
|
+
#
|
118
|
+
# @return [::Hash]
|
119
|
+
#
|
120
|
+
# @see KeyChanger#change_keys
|
121
|
+
#
|
122
|
+
# @example
|
123
|
+
# hash = { :a => 1, "b"=> 2 }
|
124
|
+
#
|
125
|
+
# hash.prepend_to_keys("foo_") # returns {
|
126
|
+
# # :foo_a => 1,
|
127
|
+
# # "foo_b"=> 2
|
128
|
+
# # }
|
129
|
+
def prepend_to_keys(str, **)
|
130
|
+
change_key_text(**) do |key|
|
94
131
|
"#{str}#{key}"
|
95
132
|
end
|
96
133
|
end
|
97
134
|
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
|
106
|
-
|
135
|
+
# Append a string to all keys
|
136
|
+
#
|
137
|
+
# @param options [::Hash]
|
138
|
+
# @option options [::TrueClass,::FalseClass]
|
139
|
+
# recursive (true)
|
140
|
+
# flag indicating transformation should be recursive
|
141
|
+
# @option options [::Symbol] type (:keep)
|
142
|
+
# type of the final key
|
143
|
+
# - keep : cast the result to the same type of the
|
144
|
+
# original key
|
145
|
+
# - string : cast the result to be {::String}
|
146
|
+
# - symbol cast the result to be {::Symbol}
|
147
|
+
#
|
148
|
+
# @return [::Hash]
|
149
|
+
#
|
150
|
+
# @see KeyChanger#change_keys
|
151
|
+
#
|
152
|
+
# @example (see #prepend_to_keys)
|
153
|
+
def append_to_keys(str, **)
|
154
|
+
change_key_text(**) do |key|
|
107
155
|
"#{key}#{str}"
|
108
156
|
end
|
109
157
|
end
|
110
158
|
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
#
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
|
126
|
-
|
127
|
-
# ex: { a:1, b:2 }.change_values{ |v| v+1 } == { a:2, b:3 }
|
128
|
-
# ex: { a:1, b:{ c:1 } }.change_values(skip_hash:false) { |v| v.to_s }
|
129
|
-
# # returns { a:"1", b:"{ c=>1 }
|
130
|
-
# ex: { a:1, b:{ c:1 } }.change_values(skip_hash:true) { |v| v.to_s }
|
131
|
-
# # returns { a:"1", b:{ c=>"1" } }
|
132
|
-
def change_values(options = {}, &block)
|
133
|
-
deep_dup.change_values!(options, &block)
|
159
|
+
# Sorts keys for hash changing the original
|
160
|
+
#
|
161
|
+
# @param options [::Hash]
|
162
|
+
# @option options [::TrueClass,::FalseClass]
|
163
|
+
# recursive (true) flag indicating recursive sorting
|
164
|
+
#
|
165
|
+
# @return [::Hash]
|
166
|
+
#
|
167
|
+
# @see KeySorter#sort
|
168
|
+
#
|
169
|
+
# @example
|
170
|
+
# hash = { b: 1, a: 2 }
|
171
|
+
#
|
172
|
+
# hash.sort_keys # changes hash to { a: 2, b: 1 }
|
173
|
+
def sort_keys!(**)
|
174
|
+
Hash::KeysSorter.new(self, **).sort
|
134
175
|
end
|
135
176
|
|
136
|
-
|
137
|
-
|
177
|
+
# Sorts keys for hash without changing the original
|
178
|
+
#
|
179
|
+
# @param options [::Hash]
|
180
|
+
# @option options [::TrueClass,::FalseClass]
|
181
|
+
# recursive (true) flag indicating recursive sorting
|
182
|
+
#
|
183
|
+
# @return [::Hash]
|
184
|
+
#
|
185
|
+
# @see KeySorter#sort
|
186
|
+
#
|
187
|
+
# @example
|
188
|
+
# hash = { b: 1, a: 2 }
|
189
|
+
#
|
190
|
+
# hash.sort_keys # returns { a: 2, b: 1 }
|
191
|
+
def sort_keys(**)
|
192
|
+
Hash::KeysSorter.new(deep_dup, **).sort
|
138
193
|
end
|
139
194
|
|
140
195
|
# Changes the key of the hash without changing it
|
@@ -143,7 +198,10 @@ module Darthjee
|
|
143
198
|
#
|
144
199
|
# @example
|
145
200
|
# hash = { a: 1, b: 2 }
|
146
|
-
# hash.remap_keys(a: :b, b: :c) # returns {
|
201
|
+
# hash.remap_keys(a: :b, b: :c) # returns {
|
202
|
+
# # b: 1,
|
203
|
+
# # c: 2
|
204
|
+
# # }
|
147
205
|
def remap_keys(remap)
|
148
206
|
dup.remap_keys!(remap)
|
149
207
|
end
|
@@ -159,15 +217,29 @@ module Darthjee
|
|
159
217
|
|
160
218
|
private
|
161
219
|
|
162
|
-
#
|
163
|
-
#
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
|
170
|
-
|
220
|
+
# @private
|
221
|
+
# @api private
|
222
|
+
#
|
223
|
+
# Changes the text of the keys
|
224
|
+
#
|
225
|
+
# @param options [::Hash]
|
226
|
+
# @option options [::TrueClass,::FalseClass]
|
227
|
+
# recursive (true)
|
228
|
+
# flag indicating transformation should be recursive
|
229
|
+
# @option options [::Symbol] type (:keep)
|
230
|
+
# type of the final key
|
231
|
+
# - keep : cast the result to the same type of the
|
232
|
+
# original key
|
233
|
+
# - string : cast the result to be {::String}
|
234
|
+
# - symbol cast the result to be {::Symbol}
|
235
|
+
#
|
236
|
+
# @yield (key) changing key block
|
237
|
+
#
|
238
|
+
# @return [::Hash]
|
239
|
+
#
|
240
|
+
# @see KeyChanger
|
241
|
+
def change_key_text(**, &)
|
242
|
+
Hash::KeyChanger.new(self).change_text(**, &)
|
171
243
|
end
|
172
244
|
end
|
173
245
|
end
|
@@ -4,11 +4,34 @@ module Darthjee
|
|
4
4
|
module CoreExt
|
5
5
|
module Hash
|
6
6
|
# @api private
|
7
|
+
#
|
8
|
+
# @author Darthjee
|
7
9
|
class KeyChanger
|
8
10
|
def initialize(hash)
|
9
11
|
@hash = hash
|
10
12
|
end
|
11
13
|
|
14
|
+
# Changes keys based on map
|
15
|
+
#
|
16
|
+
# @param keys_map [::Hash] map of
|
17
|
+
# original => final key
|
18
|
+
#
|
19
|
+
# @return [::Hash] the given hash modified
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# hash = { a: 1, 'b' => 2 }
|
23
|
+
# changer = Darthjee::CoreExt::Hash::KeyChanger.new(hash)
|
24
|
+
# remap_map = { a: 1, 'b' => 2 }
|
25
|
+
#
|
26
|
+
# changer.remap(remap_map)
|
27
|
+
#
|
28
|
+
# hash # changed to {
|
29
|
+
# # za: 1,
|
30
|
+
# # 'yb' => 2,
|
31
|
+
# # zb: nil
|
32
|
+
# # }
|
33
|
+
#
|
34
|
+
# @example (see Hash::KeyChangeable#remap_keys)
|
12
35
|
def remap(keys_map)
|
13
36
|
new_hash = {}
|
14
37
|
keys_map.each do |o, n|
|
@@ -19,57 +42,110 @@ module Darthjee
|
|
19
42
|
|
20
43
|
# Change the keys of the given hash returning the new hash
|
21
44
|
#
|
22
|
-
# @
|
45
|
+
# @param [::TrueClass,::FalseClass]
|
46
|
+
# recursive flag defining
|
47
|
+
# the change to happen also on inner hashes
|
23
48
|
#
|
24
|
-
# @
|
25
|
-
# @option options [Boolean] recursive: flag defining
|
26
|
-
# the change to happen also
|
27
|
-
# on inner hashes (defaults to: true)
|
49
|
+
# @return [::Hash] Given hash after keys tranformation
|
28
50
|
#
|
29
|
-
# @example (see Hash#change_keys)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
51
|
+
# @example (see Hash::KeyChangeable#change_keys)
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# hash = { a: 1, 'b' => { c: 3 } }
|
55
|
+
# changer = Darthjee::CoreExt::Hash::KeyChanger.new(hash)
|
56
|
+
# changer.change_keys { |k| "key_#{k}" }
|
57
|
+
#
|
58
|
+
# hash # changed to {
|
59
|
+
# # 'key_a' => 1,
|
60
|
+
# # 'key_b' => {
|
61
|
+
# # 'key_c' => 3
|
62
|
+
# # }
|
63
|
+
# # }
|
64
|
+
def change_keys(recursive: true, &)
|
65
|
+
if recursive
|
66
|
+
hash.deep_transform_keys!(&)
|
37
67
|
else
|
38
|
-
hash.transform_keys!(&
|
68
|
+
hash.transform_keys!(&)
|
39
69
|
end
|
40
70
|
end
|
41
71
|
|
42
72
|
# Performs camelization of the keys of the hash
|
43
73
|
#
|
44
|
-
# @
|
45
|
-
# @param [::
|
46
|
-
#
|
74
|
+
# @param [::Hash] options
|
75
|
+
# @param [::TrueClass,::FalseClass]
|
76
|
+
# uppercase_first_letter flag
|
47
77
|
# defining the type of CamelCase
|
78
|
+
# @option options [::TrueClass,::FalseClass]
|
79
|
+
# recursive (true) flag defining
|
80
|
+
# the change to happen also on inner hashes
|
48
81
|
#
|
49
|
-
# @
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
82
|
+
# @return [::Hash] the given hash with it's keys
|
83
|
+
# changed
|
84
|
+
#
|
85
|
+
# @see #change_keys
|
86
|
+
# @see Cameliazable#camelize_keys
|
87
|
+
#
|
88
|
+
# @example (see Cameliazable#camelize_keys)
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# hash = { my_key: { inner_key: 10 } }
|
92
|
+
# changer = Darthjee::CoreExt::Hash::KeyChanger.new(hash)
|
93
|
+
# changer.camelize_keys
|
94
|
+
# hash # changed to { MyKey: { InnerKey: 10 } }
|
95
|
+
def camelize_keys(uppercase_first_letter: true, **)
|
96
|
+
type = uppercase_first_letter ? :upper : :lower
|
56
97
|
|
57
|
-
change_keys(
|
58
|
-
|
98
|
+
change_keys(**) do |key|
|
99
|
+
key.camelize(type)
|
59
100
|
end
|
60
101
|
end
|
61
102
|
|
62
|
-
|
63
|
-
|
103
|
+
# Changes keys by performing underscore transformation
|
104
|
+
#
|
105
|
+
# @param [::hash] options
|
106
|
+
# @option options [::TrueClass,::FalseClass]
|
107
|
+
# recursive (true) flag defining
|
108
|
+
# the change to happen also on inner hashes
|
109
|
+
#
|
110
|
+
# @return [::Hash]
|
111
|
+
#
|
112
|
+
# @example (see Cameliazable#underscore_keys)
|
113
|
+
#
|
114
|
+
# @example
|
115
|
+
# hash = { myKey: { InnerKey: 10 } }
|
116
|
+
# changer = Darthjee::CoreExt::Hash::KeyChanger.new(hash)
|
117
|
+
# changer.underscore_keys
|
118
|
+
#
|
119
|
+
# hash # changed to { my_key: { inner_key: 10 } }
|
120
|
+
def underscore_keys(**)
|
121
|
+
change_keys(**, &:underscore)
|
64
122
|
end
|
65
123
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
124
|
+
# Change keys considering them to be strings
|
125
|
+
#
|
126
|
+
# @param options [::Hash]
|
127
|
+
# @param type [::Symbol] type that key will be case
|
128
|
+
# - keep: Cast the key back to the same type it was
|
129
|
+
# - string cast the key to {String}
|
130
|
+
# - symbol cast the key to {Symbol}
|
131
|
+
#
|
132
|
+
# @option options [::TrueClass,::FalseClass]
|
133
|
+
# recursive (true) flag defining
|
134
|
+
# the change to happen also on inner hashes
|
135
|
+
#
|
136
|
+
# @yield (key) key transformation block
|
137
|
+
#
|
138
|
+
# @return [::Hash] the given hash with changed keys
|
139
|
+
#
|
140
|
+
# @example
|
141
|
+
# hash = { key: { inner_key: 10 } }
|
142
|
+
# changer = Darthjee::CoreExt::Hash::KeyChanger.new(hash)
|
143
|
+
# changer.change_text { |key| key.to_s.upcase }
|
144
|
+
#
|
145
|
+
# hash # changed to { KEY: { INNER_KEY: 10 } }
|
146
|
+
def change_text(type: :keep, **)
|
147
|
+
change_keys(**) do |key|
|
148
|
+
cast_new_key yield(key), key.class, type
|
73
149
|
end
|
74
150
|
end
|
75
151
|
|
@@ -77,22 +153,47 @@ module Darthjee
|
|
77
153
|
|
78
154
|
attr_reader :hash
|
79
155
|
|
80
|
-
|
81
|
-
|
82
|
-
|
156
|
+
# @api private
|
157
|
+
# @private
|
158
|
+
#
|
159
|
+
# Cast key to correct type (String or Symbol)
|
160
|
+
#
|
161
|
+
# @param key [::String] key to be cast
|
162
|
+
# (after transformation)
|
163
|
+
# @param old_clazz [::Class] original class of the key
|
164
|
+
# @param type [::Symbol] option of type
|
165
|
+
# - keep: Cast the key back to the same type it was
|
166
|
+
# - string cast the key to {String}
|
167
|
+
# - symbol cast the key to {Symbol}
|
168
|
+
#
|
169
|
+
# @return [::String,::Symbol]
|
170
|
+
def cast_new_key(key, old_clazz, type)
|
171
|
+
case class_cast(old_clazz, type)
|
172
|
+
when :symbol
|
83
173
|
key.to_sym
|
84
|
-
when :string
|
174
|
+
when :string
|
85
175
|
key.to_s
|
86
176
|
end
|
87
177
|
end
|
88
178
|
|
89
|
-
|
90
|
-
|
91
|
-
|
179
|
+
# @api private
|
180
|
+
# @private
|
181
|
+
#
|
182
|
+
# Returns the type of the cast to be applied
|
183
|
+
#
|
184
|
+
# @param old_clazz [::Class] original class of a key
|
185
|
+
# @param type [:symbol] option of castying
|
186
|
+
# - keep: Cast the key back to the same type it was
|
187
|
+
# - string cast the key to {String}
|
188
|
+
# - symbol cast the key to {Symbol}
|
189
|
+
#
|
190
|
+
# @see #cast_new_key
|
191
|
+
#
|
192
|
+
# @return [::Symbol]
|
193
|
+
def class_cast(old_clazz, type)
|
194
|
+
return type unless type == :keep
|
92
195
|
|
93
|
-
|
94
|
-
klass = keep_class?(options) && old_clazz.to_s.downcase.to_sym
|
95
|
-
klass || options[:type]
|
196
|
+
old_clazz.to_s.downcase.to_sym
|
96
197
|
end
|
97
198
|
end
|
98
199
|
end
|
@@ -3,32 +3,69 @@
|
|
3
3
|
module Darthjee
|
4
4
|
module CoreExt
|
5
5
|
module Hash
|
6
|
+
# @api private
|
7
|
+
#
|
8
|
+
# @author Darthjee
|
9
|
+
#
|
10
|
+
# Class responsible for sorting keys of a Hash
|
6
11
|
class KeysSorter
|
12
|
+
# @param hash [::hash] hash to be sorted
|
13
|
+
# @param recursive [::TrueClass,::FalseClass]
|
14
|
+
# flag indicating to perform transformation
|
15
|
+
# recursively
|
7
16
|
def initialize(hash, recursive: true)
|
8
17
|
@hash = hash
|
9
18
|
@recursive = recursive
|
10
19
|
end
|
11
20
|
|
21
|
+
# Creates a new Hash sorting it's keys
|
22
|
+
#
|
23
|
+
# @return [::Hash] new hash
|
24
|
+
#
|
25
|
+
# @example (see KeyChangeable#sort_keys)
|
26
|
+
#
|
27
|
+
# @example Simple Usage
|
28
|
+
# hash = { key: 10, a_key: { z: 5, a: 10 } }
|
29
|
+
# sorter = Darthjee::CoreExt::Hash::KeysSorter.new(hash)
|
30
|
+
#
|
31
|
+
# sorter.sort # changes hash to {
|
32
|
+
# # a_key: { a: 10, z: 5 },
|
33
|
+
# # key: 10
|
34
|
+
# # }
|
12
35
|
def sort
|
13
|
-
|
36
|
+
hash.tap do
|
14
37
|
sorted_keys.each do |key|
|
15
|
-
|
38
|
+
hash[key] = change_value(hash.delete(key))
|
16
39
|
end
|
17
40
|
end
|
18
41
|
end
|
19
42
|
|
20
43
|
private
|
21
44
|
|
45
|
+
attr_reader :hash, :recursive
|
46
|
+
|
47
|
+
# @api private
|
48
|
+
# @private
|
49
|
+
#
|
50
|
+
# Returns all keys sorted
|
51
|
+
#
|
52
|
+
# @return [::Array<::Object>]
|
22
53
|
def sorted_keys
|
23
54
|
hash.keys.sort
|
24
55
|
end
|
25
56
|
|
57
|
+
# @api private
|
58
|
+
# @private
|
59
|
+
#
|
60
|
+
# Applies recursion when needed
|
61
|
+
#
|
62
|
+
# @return [::Object]
|
26
63
|
def change_value(value)
|
27
|
-
return value unless
|
28
|
-
value.
|
29
|
-
end
|
64
|
+
return value unless recursive
|
65
|
+
return value unless value.is_a?(Hash)
|
30
66
|
|
31
|
-
|
67
|
+
self.class.new(value).sort
|
68
|
+
end
|
32
69
|
end
|
33
70
|
end
|
34
71
|
end
|