Class: Hash

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

Instance Method Summary collapse

Instance Method Details

#bridge(*path, value: nil, delimiter: '.', symbols: true, overwrite: false) ⇒ Object

Add a hash path to a hash



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/hash/hash_path.rb', line 248

def bridge *path, value:nil, delimiter: '.', symbols: true, overwrite: false
  path = path.msplit(delimiter).flatten
  hash, part, bail, last = self, nil, false, nil
  while !path.empty? && !bail
    part = path.shift
    if part =~ /\A\[\d+\]\z/
      part = part[1..-2].to_i
    else
      part = part.to_sym if symbols
    end
    if (hash.is_a?(Hash) && hash.include?(part) || hash.is_a?(Array) && hash.size > part.to_i) && !overwrite
      bail = true if !hash[part].is_a?(Hash) && !hash[part].is_a?(Array)
      hash = hash[part] unless bail
    else
      hash[part] = path.first =~ /\A\[\d+\]\z/ ? Array.new : Hash.new
      hash = hash[part] unless bail || path.empty?
    end
  end
  hash[part] = value unless bail
  self
end

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

Merges with another hash but also merges all nested hashes and arrays/values. Based on method found @ stackoverflow.com/questions/9381553/ruby-merge-nested-hash



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

def deep_merge with, merge_arrays: true, overwrite: true
    merger = proc{ |k, v1, v2|
      if v1.is_a?(Hash) && v2.is_a?(Hash)
        v1.merge(v2, &merger)
      else
        if merge_arrays && v1.is_a?(Array) && v2.is_a?(Array)
          v1 + v2
        else
          overwrite || v1 == v2 ? v2 : [v1, v2].flatten
        end
      end
    }
    self.merge(with, &merger)
end

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



23
24
25
# File 'lib/hash/bbhash.rb', line 23

def deep_merge! with, merge_arrays: true, overwrite: true
  replace self.deep_merge(with, merge_arrays: merge_arrays, overwrite: overwrite)
end

#dive(*keys) ⇒ Object

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



220
221
222
223
224
225
226
227
228
229
# File 'lib/hash/hash_path.rb', line 220

def dive *keys
  matches = Array.new
  self.each do |k, v|
    if keys.any?{ |a| (a.is_a?(Regexp) ? a =~ k : a == k ) } then matches << v end
    if v.respond_to? :dive
      matches+= v.dive(*keys)
    end
  end
  matches
end

#expand(**args) ⇒ Object

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



239
240
241
242
243
244
245
# File 'lib/hash/hash_path.rb', line 239

def expand **args
  eh = Hash.new
  self.dup.each do |k,v|
    eh.bridge k, args.merge({value:v})
  end
  return eh
end

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



173
174
175
# File 'lib/hash/hash_path.rb', line 173

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

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



181
182
183
# File 'lib/hash/hash_path.rb', line 181

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



185
186
187
# File 'lib/hash/hash_path.rb', line 185

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



189
190
191
# File 'lib/hash/hash_path.rb', line 189

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

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



205
206
207
# File 'lib/hash/hash_path.rb', line 205

def hash_path_for value
  BBLib.hash_path_key_for self, value
end

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



193
194
195
# File 'lib/hash/hash_path.rb', line 193

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



197
198
199
# File 'lib/hash/hash_path.rb', line 197

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

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



177
178
179
# File 'lib/hash/hash_path.rb', line 177

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

#hash_pathsObject Also known as: hpaths



201
202
203
# File 'lib/hash/hash_path.rb', line 201

def hash_paths
  BBLib.hash_path_keys self
end

#keys_to_sObject

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



38
39
40
# File 'lib/hash/bbhash.rb', line 38

def keys_to_s
  self.inject({}){|memo,(k,v)| memo[k.to_s] = (v.is_a?(Hash) || v.is_a?(Array) ? v.keys_to_s : v); memo}
end

#keys_to_s!Object



42
43
44
# File 'lib/hash/bbhash.rb', line 42

def keys_to_s!
  replace(self.keys_to_s)
end

#keys_to_sym(clean: false) ⇒ Object

Converts the keys of the hash as well as any nested hashes to symbols. Based on method found @ stackoverflow.com/questions/800122/best-way-to-convert-strings-to-symbols-in-hash



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

def keys_to_sym clean: false
  self.inject({}){|memo,(k,v)| memo[clean ? k.to_s.to_clean_sym : k.to_s.to_sym] = (v.is_a?(Hash) || v.is_a?(Array) ? v.keys_to_sym(clean:clean) : v); memo}
end

#keys_to_sym!(clean: false) ⇒ Object



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

def keys_to_sym! clean: false
  replace(self.keys_to_sym clean:clean)
end

#path_hashObject Also known as: phash, _ph



63
64
65
# File 'lib/hash/path_hash.rb', line 63

def path_hash
  BBLib::path_hash(self)
end

#path_proc(action, paths, *args) ⇒ Object Also known as: hash_path_proc



4
5
6
# File 'lib/hash/hash_path_proc.rb', line 4

def path_proc action, paths, *args
  BBLib.hash_path_proc self, action, paths, *args
end

#reverseObject

Reverses the order of keys in the Hash



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

def reverse
  self.to_a.reverse.to_h
end

#reverse!Object



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

def reverse!
  replace self.reverse
end

#squish(delimiter: '.') ⇒ Object

Turns nested values’ keys into delimiter separated paths



232
233
234
235
236
# File 'lib/hash/hash_path.rb', line 232

def squish delimiter: '.'
  sh = Hash.new
  BBLib.hash_path_nav(self.dup, nil, delimiter){ |k, v| sh[k] = v }
  sh
end

#to_xml(level: 0, key: nil) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/hash/bbhash.rb', line 60

def to_xml level: 0, key:nil
  map do |k,v|
    nested = v.respond_to?(:to_xml)
    array = v.is_a?(Array)
    value = nested ? v.to_xml(level:level + (array ? 0 : 1), key:k) : v
    (array ? '' : ("\t" * level + "<#{k}>\n")) +
    (nested ? '' : "\t" * (level + 1)) +
    "#{value}\n" +
    "\t" * level +
    (array ? '' : "</#{k}>\n")
  end.join.split("\n").reject{ |r| r.strip == '' }.join("\n")
end

#unshift(hash, value = nil) ⇒ Object



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

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