Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/hash_path/proc.rb,
lib/hash/bbhash.rb,
lib/hash_path/hash_path.rb,
lib/hash_path/path_hash.rb

Overview

Monkey Patches

Direct Known Subclasses

BBLib::HashStruct

Instance Method Summary collapse

Instance Method Details

#deep_merge(with, merge_arrays: true, overwrite: true, uniq: false) ⇒ Object

Merges with another hash but also merges all nested hashes and arrays/values.



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/hash/bbhash.rb', line 7

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

#deep_merge!(*args) ⇒ Object

In place version of deep_merge



21
22
23
# File 'lib/hash/bbhash.rb', line 21

def deep_merge!(*args)
  replace deep_merge(*args)
end

#diff(hash) ⇒ Object

Displays all of the differences between this hash and another. Checks both key and value pairs.



68
69
70
# File 'lib/hash/bbhash.rb', line 68

def diff(hash)
  to_a.diff(hash.to_a).to_h
end

#dive(*keys) ⇒ Object

Returns all matching values with a specific key (or keys) recursively within a Hash (including nested Arrays)



73
74
75
76
77
78
79
80
# File 'lib/hash/bbhash.rb', line 73

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

#except(*args) ⇒ Object

Returns a version of the hash with the specified keys removed.



138
139
140
# File 'lib/hash/bbhash.rb', line 138

def except(*args)
  reject { |k, _v| args.include?(k) }
end

#expandObject

Expands keys in a hash using a delimiter. Opposite of squish.



124
125
126
127
128
129
130
# File 'lib/hash/bbhash.rb', line 124

def expand
  {}.to_tree_hash.tap do |hash|
    each do |k, v|
      hash.bridge(k => v)
    end
  end.value
end

#hash_path(*path) ⇒ Object Also known as: hpath



111
112
113
# File 'lib/hash_path/hash_path.rb', line 111

def hash_path(*path)
  BBLib.hash_path self, *path
end

#hash_path_copy(*paths) ⇒ Object Also known as: hpath_copy



119
120
121
# File 'lib/hash_path/hash_path.rb', line 119

def hash_path_copy(*paths)
  BBLib.hash_path_copy self, *paths
end

#hash_path_copy_to(to, *paths) ⇒ Object Also known as: hpath_copy_to



123
124
125
# File 'lib/hash_path/hash_path.rb', line 123

def hash_path_copy_to(to, *paths)
  BBLib.hash_path_copy_to self, to, *paths
end

#hash_path_delete(*paths) ⇒ Object Also known as: hpath_delete



127
128
129
# File 'lib/hash_path/hash_path.rb', line 127

def hash_path_delete(*paths)
  BBLib.hash_path_delete self, *paths
end

#hash_path_for(value) ⇒ Object Also known as: hpath_for



143
144
145
# File 'lib/hash_path/hash_path.rb', line 143

def hash_path_for(value)
  BBLib.hash_path_key_for self, value
end

#hash_path_move(*paths) ⇒ Object Also known as: hpath_move



131
132
133
# File 'lib/hash_path/hash_path.rb', line 131

def hash_path_move(*paths)
  BBLib.hash_path_move self, *paths
end

#hash_path_move_to(to, *paths) ⇒ Object Also known as: hpath_move_to



135
136
137
# File 'lib/hash_path/hash_path.rb', line 135

def hash_path_move_to(to, *paths)
  BBLib.hash_path_move_to self, to, *paths
end

#hash_path_proc(*args) ⇒ Object Also known as: hpath_proc



79
80
81
# File 'lib/hash_path/proc.rb', line 79

def hash_path_proc(*args)
  BBLib::HashPathProc.new(*args).process(self)
end

#hash_path_set(*paths) ⇒ Object Also known as: hpath_set



115
116
117
# File 'lib/hash_path/hash_path.rb', line 115

def hash_path_set(*paths)
  BBLib.hash_path_set self, *paths
end

#hash_pathsObject Also known as: hpaths



139
140
141
# File 'lib/hash_path/hash_path.rb', line 139

def hash_paths
  BBLib.hash_path_keys self
end

#hmapObject

Map for hash that automatically converts the yield block to a hash. Each yield must produce an array with exactly two elements.



161
162
163
164
# File 'lib/hash/bbhash.rb', line 161

def hmap
  return map unless block_given?
  map { |k, v| yield(k, v) }.compact.to_h
end

#keys_to_s(recursive: true) ⇒ Object

Converts the keys of the hash as well as any nested hashes to strings.



39
40
41
42
43
# File 'lib/hash/bbhash.rb', line 39

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

#keys_to_s!(recursive: true) ⇒ Object

In place version of keys_to_s



46
47
48
# File 'lib/hash/bbhash.rb', line 46

def keys_to_s!(recursive: true)
  replace(keys_to_s(recursive: recursive))
end

#keys_to_sym(clean: false, recursive: true) ⇒ Object

Converts the keys of the hash as well as any nested hashes to symbols.



26
27
28
29
30
31
# File 'lib/hash/bbhash.rb', line 26

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

#keys_to_sym!(clean: false, recursive: true) ⇒ Object

In place version of keys_to_sym



34
35
36
# File 'lib/hash/bbhash.rb', line 34

def keys_to_sym!(clean: false, recursive: true)
  replace(keys_to_sym(clean: clean, recursive: recursive))
end

#kmapObject

Run a map iterator over the keys in the hash without changing the values.



154
155
156
157
# File 'lib/hash/bbhash.rb', line 154

def kmap
  return map unless block_given?
  map { |k, v| [yield(k), v] }.to_h
end

#only(*args) ⇒ Object

Returns a version of the hash not including the specified keys



133
134
135
# File 'lib/hash/bbhash.rb', line 133

def only(*args)
  select { |k, _v| args.include?(k) }
end

#path_hashObject Also known as: phash, _ph



68
69
70
# File 'lib/hash_path/path_hash.rb', line 68

def path_hash
  BBLib.path_hash(self)
end

#path_nav(obj, path = '', delimiter = '.', &block) ⇒ Object

Navigate a hash using a dot delimited path.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/hash/bbhash.rb', line 83

def path_nav(obj, path = '', delimiter = '.', &block)
  case obj
  when Hash
    if obj.empty?
      yield path, obj
    else
      obj.each do |k, v|
        path_nav(
          v,
          (path ? [path, k.to_s.gsub(delimiter, "\\#{delimiter}")].join(delimiter) : k.to_s.gsub(delimiter, "\\#{delimiter}")).to_s,
          delimiter,
          &block
        )
      end
    end
  when Array
    if obj.empty?
      yield path, obj
    else
      obj.each_with_index do |ob, index|
        path_nav(
          ob,
          (path ? [path, "[#{index}]"].join(delimiter) : "[#{index}]").to_s,
          delimiter,
          &block
        )
      end
    end
  else
    yield path, obj
  end
end

#reverseObject

Reverses the order of keys in the Hash



51
52
53
# File 'lib/hash/bbhash.rb', line 51

def reverse
  to_a.reverse.to_h
end

#reverse!Object

In place version of reverse



56
57
58
# File 'lib/hash/bbhash.rb', line 56

def reverse!
  replace(reverse)
end

#squish(delimiter: '.') ⇒ Object

Turns nested values’ keys into delimiter separated paths



117
118
119
120
121
# File 'lib/hash/bbhash.rb', line 117

def squish(delimiter: '.')
  sh = {}
  path_nav(dup, nil, delimiter) { |k, v| sh[k] = v }
  sh
end

#to_tree_hashObject

Convert this hash into a TreeHash object.



143
144
145
# File 'lib/hash/bbhash.rb', line 143

def to_tree_hash
  TreeHash.new(self)
end

#unshift(hash, value = nil) ⇒ Object

Like unshift for Arrays. Adds a key to the beginning of a Hash rather than the end.



61
62
63
64
# File 'lib/hash/bbhash.rb', line 61

def unshift(hash, value = nil)
  hash = { hash => value } unless hash.is_a?(Hash)
  replace(hash.merge(self).merge(hash))
end

#vmapObject

Run a map iterator over the values in the hash without changing the keys.



148
149
150
151
# File 'lib/hash/bbhash.rb', line 148

def vmap
  return map unless block_given?
  map { |k, v| [k, yield(v)] }.to_h
end