Module: Transproc::HashTransformations
- Extended by:
- Registry
- Defined in:
- lib/transproc/hash.rb
Overview
Transformation functions for Hash objects
Class Method Summary collapse
-
.accept_keys(hash, keys) ⇒ Hash
Accepts specified keys from a hash.
-
.accept_keys!(hash, keys) ⇒ Object
Same as ‘:accept_keys` but mutates the hash.
-
.copy_keys(hash, mapping) ⇒ Hash
Copy all keys in a hash using provided mapping hash.
-
.copy_keys!(hash, mapping) ⇒ Object
Same as ‘:copy_keys` but mutates the hash.
-
.deep_merge(hash, other) ⇒ Hash
Merge a hash recursively.
-
.deep_symbolize_keys(hash) ⇒ Hash
Symbolize keys in a hash recursively.
-
.eval_values(hash, args, filters = []) ⇒ Object
Recursively evaluate hash values if they are procs/lambdas.
-
.fold(hash, key, tuple_key) ⇒ Hash
Folds array of tuples to array of values from a specified key.
-
.fold!(hash, key, tuple_key) ⇒ Object
Same as ‘:fold` but mutates the hash.
-
.map_keys(hash, fn) ⇒ Hash
Map all keys in a hash with the provided transformation function.
-
.map_keys!(hash, fn) ⇒ Object
Same as ‘:map_keys` but mutates the hash.
-
.map_value(hash, key, fn) ⇒ Hash
Map a key in a hash with the provided transformation function.
-
.map_value!(hash, key, fn) ⇒ Object
Same as ‘:map_value` but mutates the hash.
-
.map_values(hash, fn) ⇒ Hash
Map all values in a hash using transformation function.
-
.map_values!(hash, fn) ⇒ Hash
Same as ‘:map_values` but mutates the hash.
-
.nest(hash, key, keys) ⇒ Hash
Nest values from specified keys under a new key.
-
.nest!(hash, root, keys) ⇒ Object
Same as ‘:nest` but mutates the hash.
-
.reject_keys(hash, keys) ⇒ Hash
Rejects specified keys from a hash.
-
.reject_keys!(hash, keys) ⇒ Object
Same as ‘:reject_keys` but mutates the hash.
-
.rename_keys(hash, mapping) ⇒ Hash
Rename all keys in a hash using provided mapping hash.
-
.rename_keys!(hash, mapping) ⇒ Object
Same as ‘:rename_keys` but mutates the hash.
-
.split(hash, key, keys) ⇒ Array<Hash>
Splits hash to array by all values from a specified key.
-
.stringify_keys(hash) ⇒ Hash
Stringify all keys in a hash.
-
.stringify_keys!(hash) ⇒ Object
Same as ‘:stringify_keys` but mutates the hash.
-
.symbolize_keys(hash) ⇒ Hash
Symbolize all keys in a hash.
-
.symbolize_keys!(hash) ⇒ Object
Same as ‘:symbolize_keys` but mutates the hash.
-
.unwrap(hash, root, keys = nil) ⇒ Hash
Collapse a nested hash from a specified key.
-
.unwrap!(hash, root, selected = nil) ⇒ Object
Same as ‘:unwrap` but mutates the hash.
Methods included from Registry
Class Method Details
.accept_keys(hash, keys) ⇒ Hash
Accepts specified keys from a hash
245 246 247 |
# File 'lib/transproc/hash.rb', line 245 def self.accept_keys(hash, keys) accept_keys!(Hash[hash], keys) end |
.accept_keys!(hash, keys) ⇒ Object
Same as ‘:accept_keys` but mutates the hash
254 255 256 |
# File 'lib/transproc/hash.rb', line 254 def self.accept_keys!(hash, keys) reject_keys!(hash, hash.keys - keys) end |
.copy_keys(hash, mapping) ⇒ Hash
Copy all keys in a hash using provided mapping hash
190 191 192 |
# File 'lib/transproc/hash.rb', line 190 def self.copy_keys(hash, mapping) copy_keys!(Hash[hash], mapping) end |
.copy_keys!(hash, mapping) ⇒ Object
Same as ‘:copy_keys` but mutates the hash
199 200 201 202 203 204 205 206 |
# File 'lib/transproc/hash.rb', line 199 def self.copy_keys!(hash, mapping) mapping.each do |original_key, new_keys| [*new_keys].each do |new_key| hash[new_key] = hash[original_key] end end hash end |
.deep_merge(hash, other) ⇒ Hash
Merge a hash recursively
478 479 480 481 482 483 484 485 486 487 |
# File 'lib/transproc/hash.rb', line 478 def self.deep_merge(hash, other) Hash[hash].merge(other) do |_, original_value, new_value| if original_value.respond_to?(:to_hash) && new_value.respond_to?(:to_hash) deep_merge(Hash[original_value], Hash[new_value]) else new_value end end end |
.deep_symbolize_keys(hash) ⇒ Hash
Symbolize keys in a hash recursively
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/transproc/hash.rb', line 83 def self.deep_symbolize_keys(hash) hash.each_with_object({}) do |(key, value), output| output[key.to_sym] = case value when Hash deep_symbolize_keys(value) when Array value.map { |item| item.is_a?(Hash) ? deep_symbolize_keys(item) : item } else value end end end |
.eval_values(hash, args, filters = []) ⇒ Object
Recursively evaluate hash values if they are procs/lambdas
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/transproc/hash.rb', line 440 def self.eval_values(hash, args, filters = []) hash.each_with_object({}) do |(key, value), output| output[key] = case value when Proc if filters.empty? || filters.include?(key) value.call(*args) else value end when Hash eval_values(value, args, filters) when Array value.map { |item| item.is_a?(Hash) ? eval_values(item, args, filters) : item } else value end end end |
.fold(hash, key, tuple_key) ⇒ Hash
Folds array of tuples to array of values from a specified key
366 367 368 |
# File 'lib/transproc/hash.rb', line 366 def self.fold(hash, key, tuple_key) fold!(Hash[hash], key, tuple_key) end |
.fold!(hash, key, tuple_key) ⇒ Object
Same as ‘:fold` but mutates the hash
375 376 377 |
# File 'lib/transproc/hash.rb', line 375 def self.fold!(hash, key, tuple_key) hash.update(key => ArrayTransformations.extract_key(hash[key], tuple_key)) end |
.map_keys(hash, fn) ⇒ Hash
Map all keys in a hash with the provided transformation function
31 32 33 |
# File 'lib/transproc/hash.rb', line 31 def self.map_keys(hash, fn) map_keys!(Hash[hash], fn) end |
.map_keys!(hash, fn) ⇒ Object
Same as ‘:map_keys` but mutates the hash
40 41 42 43 |
# File 'lib/transproc/hash.rb', line 40 def self.map_keys!(hash, fn) hash.keys.each { |key| hash[fn[key]] = hash.delete(key) } hash end |
.map_value(hash, key, fn) ⇒ Hash
Map a key in a hash with the provided transformation function
269 270 271 |
# File 'lib/transproc/hash.rb', line 269 def self.map_value(hash, key, fn) hash.merge(key => fn[hash[key]]) end |
.map_value!(hash, key, fn) ⇒ Object
Same as ‘:map_value` but mutates the hash
278 279 280 |
# File 'lib/transproc/hash.rb', line 278 def self.map_value!(hash, key, fn) hash.update(key => fn[hash[key]]) end |
.map_values(hash, fn) ⇒ Hash
Map all values in a hash using transformation function
134 135 136 |
# File 'lib/transproc/hash.rb', line 134 def self.map_values(hash, fn) map_values!(Hash[hash], fn) end |
.map_values!(hash, fn) ⇒ Hash
Same as ‘:map_values` but mutates the hash
147 148 149 150 |
# File 'lib/transproc/hash.rb', line 147 def self.map_values!(hash, fn) hash.each { |key, value| hash[key] = fn[value] } hash end |
.nest(hash, key, keys) ⇒ Hash
Nest values from specified keys under a new key
293 294 295 |
# File 'lib/transproc/hash.rb', line 293 def self.nest(hash, key, keys) nest!(Hash[hash], key, keys) end |
.nest!(hash, root, keys) ⇒ Object
Same as ‘:nest` but mutates the hash
302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/transproc/hash.rb', line 302 def self.nest!(hash, root, keys) nest_keys = hash.keys & keys if nest_keys.size > 0 child = Hash[nest_keys.zip(nest_keys.map { |key| hash.delete(key) })] old_nest = hash[root] new_nest = old_nest.is_a?(Hash) ? old_nest.merge(child) : child hash.update(root => new_nest) else hash.update(root => {}) end end |
.reject_keys(hash, keys) ⇒ Hash
Rejects specified keys from a hash
220 221 222 |
# File 'lib/transproc/hash.rb', line 220 def self.reject_keys(hash, keys) reject_keys!(Hash[hash], keys) end |
.reject_keys!(hash, keys) ⇒ Object
Same as ‘:reject_keys` but mutates the hash
229 230 231 |
# File 'lib/transproc/hash.rb', line 229 def self.reject_keys!(hash, keys) hash.reject { |k, _| keys.include?(k) } end |
.rename_keys(hash, mapping) ⇒ Hash
Rename all keys in a hash using provided mapping hash
164 165 166 |
# File 'lib/transproc/hash.rb', line 164 def self.rename_keys(hash, mapping) rename_keys!(Hash[hash], mapping) end |
.rename_keys!(hash, mapping) ⇒ Object
Same as ‘:rename_keys` but mutates the hash
173 174 175 176 |
# File 'lib/transproc/hash.rb', line 173 def self.rename_keys!(hash, mapping) mapping.each { |k, v| hash[v] = hash.delete(k) if hash.has_key?(k) } hash end |
.split(hash, key, keys) ⇒ Array<Hash>
Splits hash to array by all values from a specified key
The operation adds missing keys extracted from the array to regularize the output.
407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/transproc/hash.rb', line 407 def self.split(hash, key, keys) list = Array(hash[key]) return [hash.reject { |k, _| k == key }] if list.empty? existing = list.flat_map(&:keys).uniq grouped = existing - keys ungrouped = existing & keys list = ArrayTransformations.group(list, key, grouped) if grouped.any? list = list.map { |item| item.merge(reject_keys(hash, [key])) } ArrayTransformations.add_keys(list, ungrouped) end |
.stringify_keys(hash) ⇒ Hash
Stringify all keys in a hash
110 111 112 |
# File 'lib/transproc/hash.rb', line 110 def self.stringify_keys(hash) stringify_keys!(Hash[hash]) end |
.stringify_keys!(hash) ⇒ Object
Same as ‘:stringify_keys` but mutates the hash
119 120 121 |
# File 'lib/transproc/hash.rb', line 119 def self.stringify_keys!(hash) map_keys!(hash, Coercions[:to_string].fn) end |
.symbolize_keys(hash) ⇒ Hash
Symbolize all keys in a hash
56 57 58 |
# File 'lib/transproc/hash.rb', line 56 def self.symbolize_keys(hash) symbolize_keys!(Hash[hash]) end |
.symbolize_keys!(hash) ⇒ Object
Same as ‘:symbolize_keys` but mutates the hash
65 66 67 |
# File 'lib/transproc/hash.rb', line 65 def self.symbolize_keys!(hash) map_keys!(hash, Coercions[:to_symbol].fn) end |
.unwrap(hash, root, keys = nil) ⇒ Hash
Collapse a nested hash from a specified key
326 327 328 329 |
# File 'lib/transproc/hash.rb', line 326 def self.unwrap(hash, root, keys = nil) copy = Hash[hash].merge(root => Hash[hash[root]]) unwrap!(copy, root, keys) end |
.unwrap!(hash, root, selected = nil) ⇒ Object
Same as ‘:unwrap` but mutates the hash
336 337 338 339 340 341 342 343 344 345 |
# File 'lib/transproc/hash.rb', line 336 def self.unwrap!(hash, root, selected = nil) if nested_hash = hash[root] keys = nested_hash.keys keys &= selected if selected hash.update(Hash[keys.zip(keys.map { |key| nested_hash.delete(key) })]) hash.delete(root) if nested_hash.empty? end hash end |