class Hash
Monkey patches
Public Instance Methods
Merges with another hash but also merges all nested hashes and arrays/values.
# File lib/bblib/core/util/hash.rb, line 4 def deep_merge(with, merge_arrays: true, overwrite: true, uniq: false) merger = proc do |_k, v1, v2| if BBLib.are_all?(Hash, v1, v2) v1.merge(v2, &merger) elsif merge_arrays && BBLib.are_all?(Array, v1, v2) uniq ? (v1 + v2).uniq : v1 + v2 else overwrite || v1 == v2 ? v2 : (uniq ? [v1, v2].flatten.uniq : [v1, v2].flatten) end end merge(with, &merger) end
In place version of deep_merge
# File lib/bblib/core/util/hash.rb, line 18 def deep_merge!(*args) replace deep_merge(*args) end
Displays all of the differences between this hash and another. Checks both key and value pairs.
# File lib/bblib/core/util/hash.rb, line 65 def diff(hash) to_a.diff(hash.to_a).to_h end
Returns all matching values with a specific key (or keys) recursively within a Hash
(including nested Arrays)
# File lib/bblib/core/util/hash.rb, line 70 def dive(*keys) matches = [] each do |k, v| matches << v if keys.any? { |key| (key.is_a?(Regexp) ? key =~ k : key == k) } matches += v.dive(*keys) if v.respond_to?(:dive) end matches end
Returns a version of the hash with the specified keys removed.
# File lib/bblib/core/util/hash.rb, line 135 def except(*args) reject { |k, _v| args.include?(k) } end
Expands keys in a hash using a delimiter. Opposite of squish.
# File lib/bblib/core/util/hash.rb, line 121 def expand {}.to_tree_hash.tap do |hash| each do |k, v| hash.bridge(k => v) end end.value end
# File lib/bblib/core/hash_path/hash_path.rb, line 109 def hash_path(*path) BBLib.hash_path self, *path end
# File lib/bblib/core/hash_path/hash_path.rb, line 117 def hash_path_copy(*paths) BBLib.hash_path_copy self, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 121 def hash_path_copy_to(to, *paths) BBLib.hash_path_copy_to self, to, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 125 def hash_path_delete(*paths) BBLib.hash_path_delete self, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 141 def hash_path_for(value) BBLib.hash_path_key_for self, value end
# File lib/bblib/core/hash_path/hash_path.rb, line 129 def hash_path_move(*paths) BBLib.hash_path_move self, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 133 def hash_path_move_to(to, *paths) BBLib.hash_path_move_to self, to, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 113 def hash_path_set(*paths) BBLib.hash_path_set self, *paths end
# File lib/bblib/core/hash_path/hash_path.rb, line 137 def hash_paths BBLib.hash_path_keys self end
Map for hash that automatically converts the yield block to a hash. Each yield must produce an array with exactly two elements.
# File lib/bblib/core/util/hash.rb, line 158 def hmap return map unless block_given? map { |k, v| yield(k, v) }.compact.to_h end
Converts the keys of the hash as well as any nested hashes to strings.
# File lib/bblib/core/util/hash.rb, line 36 def keys_to_s(recursive: true) each_with_object({}) do |(k, v), memo| memo[k.to_s] = recursive && v.respond_to?(:keys_to_sym) ? v.keys_to_s : v end end
In place version of keys_to_s
# File lib/bblib/core/util/hash.rb, line 43 def keys_to_s!(recursive: true) replace(keys_to_s(recursive: recursive)) end
Converts the keys of the hash as well as any nested hashes to symbols.
# File lib/bblib/core/util/hash.rb, line 23 def keys_to_sym(clean: false, recursive: true) each_with_object({}) do |(k, v), memo| key = clean ? k.to_s.to_clean_sym : k.to_s.to_sym memo[key] = recursive && v.respond_to?(:keys_to_sym) ? v.keys_to_sym(clean: clean) : v end end
In place version of keys_to_sym
# File lib/bblib/core/util/hash.rb, line 31 def keys_to_sym!(clean: false, recursive: true) replace(keys_to_sym(clean: clean, recursive: recursive)) end
Run a map iterator over the keys in the hash without changing the values.
# File lib/bblib/core/util/hash.rb, line 151 def kmap return map unless block_given? map { |k, v| [yield(k), v] }.to_h end
Returns a version of the hash not including the specified keys
# File lib/bblib/core/util/hash.rb, line 130 def only(*args) select { |k, _v| args.include?(k) } end
Reverses the order of keys in the Hash
# File lib/bblib/core/util/hash.rb, line 48 def reverse to_a.reverse.to_h end
In place version of reverse
# File lib/bblib/core/util/hash.rb, line 53 def reverse! replace(reverse) end
Turns nested values' keys into delimiter separated paths
# File lib/bblib/core/util/hash.rb, line 114 def squish(delimiter: '.') sh = {} path_nav(dup, nil, delimiter) { |k, v| sh[k] = v } sh end
# File lib/bblib/core/classes/hash_struct.rb, line 38 def to_hash_struct(recursive = true) hash = recursive ? self.hmap { |k, v| [k, v.respond_to?(:to_hash_struct) ? v.to_hash_struct(recursive) : v] } : self BBLib::HashStruct.new.merge(hash) end
Convert this hash into a TreeHash
object.
# File lib/bblib/core/util/hash.rb, line 140 def to_tree_hash TreeHash.new(self) end
Like unshift for Arrays. Adds a key to the beginning of a Hash
rather than the end.
# File lib/bblib/core/util/hash.rb, line 58 def unshift(hash, value = nil) hash = { hash => value } unless hash.is_a?(Hash) replace(hash.merge(self).merge(hash)) end
Run a map iterator over the values in the hash without changing the keys.
# File lib/bblib/core/util/hash.rb, line 145 def vmap return map unless block_given? map { |k, v| [k, yield(v)] }.to_h end