Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/imw/utils/extensions/hash.rb

Direct Known Subclasses

IMW::Repository

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.zip(keys, values, default = nil, &block) ⇒ Object

Create a hash from an array of keys and corresponding values.



25
26
27
28
29
# File 'lib/imw/utils/extensions/hash.rb', line 25

def self.zip(keys, values, default=nil, &block)
  hash = block_given? ? Hash.new(&block) : Hash.new(default)
  keys.zip(values) { |k,v| hash[k]=v }
  hash
end

Instance Method Details

#assoc(key) ⇒ Object

This is polymorphic to Array#assoc – that is, it allows you treat a Hash and an array of pairs equivalently using assoc(). We remind you that Array#assoc

"Searches through an array whose elements are also arrays comparing obj
 with the first element of each contained array using obj.== . Returns the
 first contained array that matches (that is, the first associated array)
 or nil if no match is found. See also Array#rassoc."

Note that this returns an /array/ of [key, val] pairs.



136
137
138
# File 'lib/imw/utils/extensions/hash.rb', line 136

def assoc(key)
  self.include?(key)   ? [key, self[key]] : nil
end

#compactObject

remove all key-value pairs where the value is nil



170
171
172
# File 'lib/imw/utils/extensions/hash.rb', line 170

def compact
  reject{|k,v| v.nil? }
end

#compact!Object

Replaces the hash with its compacted self



175
176
177
# File 'lib/imw/utils/extensions/hash.rb', line 175

def compact!
  replace(compact)
end

#deep_merge(second) ⇒ Object

Merges self with another hash, recursively.

first =

:balls=> "monkey",
:data=> {
  :name=> {:first=> "Sam", :middle=>"I", :last=>"am"}}

second = {

:data=> {
  :name=> {:middle=>["you", "me", "everyone we know"], :last => "are"}},
1    => [1,2,5] }

p first.deep_merge(second) # => {:data=>{:name=>{:last=>“are”, :middle=>[“you”, “me”, “everyone we know”], :first=>“Sam”}}, 1=>[1, 2, 5], :balls=>“monkey”} from snippets.dzone.com/posts/show/4706 From: pastie.textmate.org/pastes/30372, Elliott Hird



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/imw/utils/extensions/hash.rb', line 58

def deep_merge(second)
  target = dup
  second.keys.each do |key|
    if second[key].is_a?(Hash) && self[key].is_a?(Hash)
      target[key] = target[key].deep_merge(second[key])
    else
      target[key] = second[key]
    end
  end
  target
end

#deep_merge!(second) ⇒ Object

Merges self in-place with another hash, recursively.

first =

:balls=> "monkey",
:data=> {
  :name=> {:first=> "Sam", :middle=>"I", :last=>"am"}}

second = {

:data=> {
  :name=> {:middle=>["you", "me", "everyone we know"], :last => "are"}},
1    => [1,2,5] }

p first.deep_merge(second) # => {:data=>{:name=>{:last=>“are”, :middle=>[“you”, “me”, “everyone we know”], :first=>“Sam”}}, 1=>[1, 2, 5], :balls=>“monkey”}

From: www.gemtacular.com/gemdocs/cerberus-0.2.2/doc/classes/Hash.html File lib/cerberus/utils.rb, line 42



86
87
88
89
90
91
92
93
94
95
# File 'lib/imw/utils/extensions/hash.rb', line 86

def deep_merge!(second)
  second.keys.each do |key|
    if second[key].is_a?(Hash) && self[key].is_a?(Hash)
      self[key].deep_merge!(second[key])
    else
      self[key] = second[key]
    end
  end
  self
end

#dispatch(default = nil, &block) ⇒ Object

Works like Enumerable::find but loops over the keys of this Hash instead of of arrays of [key,value] and, in the absence of a matching key, doesn’t call the default argument, merely returns it instead.



183
184
185
186
# File 'lib/imw/utils/extensions/hash.rb', line 183

def dispatch(default=nil, &block)
  match = self.keys.find(nil,&block)
  match ? self[match] : default
end

#dump(uri) ⇒ Object

Dump the data from this Hash into the given uri.



205
206
207
# File 'lib/imw/utils/extensions/hash.rb', line 205

def dump uri
  IMW.open(uri).dump(self)
end

#from_pairsObject

Turns a collection of pairs into a hash. The first of each pair make the keys and the second the values. Elements with length longer than two will lose those values.

If there are multiple values of



37
38
39
40
41
# File 'lib/imw/utils/extensions/hash.rb', line 37

def from_pairs()
  hsh = { }
  self.each{ |k,v| hsh[k] = v }
  hsh
end

#keep_merge(second) ⇒ Object

Merge another array with this one, accumulating values that appear in both into arrays.

Note: array values will be flatten’ed. Sorry.

first =

:balls=> "monkey",
:data=> {
  :name=> {:first=> "Sam", :middle=>"I", :last=>"am"}}

second = {

:data=> {
  :name=> {:middle=>["you", "me", "everyone we know"], :last => "are"}},
1    => [1,2,5] }

p first.deep_merge(second) # => {:data=>{:name=>{:last=>“are”, :middle=>[“you”, “me”, “everyone we know”], :first=>“Sam”}}, 1=>[1, 2, 5], :balls=>“monkey”} p first.keep_merge(second) # => {:data=>{:name=>{:last=>[“am”, “are”], :middle=>[“I”, “you”, “me”, “everyone we know”], :first=>“Sam”}}, 1=>[1, 2, 5], :balls=>“monkey”}



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/imw/utils/extensions/hash.rb', line 115

def keep_merge(second)
  target = dup
  second.each do |key, val2|
    if second[key].is_a?(Hash) && self[key].is_a?(Hash)
      target[key] = target[key].keep_merge(val2)
    else
      target[key] = target.include?(key) ? [target[key], val2].flatten.uniq : val2
    end
  end
  target
end

#quote_keys_with(final_string = nil) ⇒ Object

Return the elements of this hash in a pretty-printed string, inserting final_string between the last two items.

>> {:one => 1, :two => 2, :three => 3}.quote_keys_with "or"
`one', `two', or `three'


10
11
12
# File 'lib/imw/utils/extensions/hash.rb', line 10

def quote_keys_with final_string = nil
  self.keys.quote_items_with final_string
end

#rassoc(key) ⇒ Object



139
140
141
# File 'lib/imw/utils/extensions/hash.rb', line 139

def rassoc(key)
  self.has_value?(key) ? [key, self[key]] : nil
end

#reverse_merge(other_hash) ⇒ Object

Stolen from ActiveSupport::CoreExtensions::Hash::ReverseMerge.



15
16
17
# File 'lib/imw/utils/extensions/hash.rb', line 15

def reverse_merge(other_hash)
  other_hash.merge(self)
end

#reverse_merge!(other_hash) ⇒ Object

Stolen from ActiveSupport::CoreExtensions::Hash::ReverseMerge.



20
21
22
# File 'lib/imw/utils/extensions/hash.rb', line 20

def reverse_merge!(other_hash)
  replace(reverse_merge(other_hash))
end

#slice(*keys) ⇒ Object

Slice a hash to include only the given keys. This is useful for limiting an options hash to valid keys before passing to a method:

def search(criteria = {})
  assert_valid_keys(:mass, :velocity, :time)
end

search(options.slice(:mass, :velocity, :time))

Returns a new hash with only the given keys.



158
159
160
161
162
# File 'lib/imw/utils/extensions/hash.rb', line 158

def slice(*keys)
  require 'set'
  allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
  reject { |key,| !allowed.include?(key) }
end

#slice!(*keys) ⇒ Object

Replaces the hash with only the given keys.



165
166
167
# File 'lib/imw/utils/extensions/hash.rb', line 165

def slice!(*keys)
  replace(slice(*keys))
end

#terminals(&block) ⇒ Object

Recurses through the pairs of this Hash collecting all String or Symbol “terminal” nodes.



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/imw/utils/extensions/hash.rb', line 191

def terminals &block
  terminals = []
  each_value do |value|
    if value.respond_to? :terminals then
      terminals += value.terminals
    else
      terminals << value
    end
  end
  terminals.map! {|terminal| yield terminal } if block
  terminals
end

#to_openstructObject

Allows loading ostruct directly from YAML



144
145
146
# File 'lib/imw/utils/extensions/hash.rb', line 144

def to_openstruct
  map{ |el| el.to_openstruct }
end