Class: Enumerable::Hashifier

Inherits:
Object
  • Object
show all
Defined in:
lib/core/facets/enumerable/hashify.rb

Instance Method Summary collapse

Constructor Details

#initialize(enum) ⇒ Hashifier

Returns a new instance of Hashifier.


57
58
59
# File 'lib/core/facets/enumerable/hashify.rb', line 57

def initialize(enum)
  @enum = enum
end

Instance Method Details

#associateObject Also known as: assoc

When a mixed or multi-element associative array is used, the result is as follows:

a = [ [:a,1,2], [:b,2], [:c], :d ]
a.hashify.assoc  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the first entry of any subelements are the same, then the value will be set to the last occurring value.

a = [ :x, [:x], [:x,1,2], [:x,3], [:x,4] ]
a.hashify.assoc  #=> { :x=>[4] }

97
98
99
100
101
102
103
# File 'lib/core/facets/enumerable/hashify.rb', line 97

def associate
  h = {}
  each do |k,*v|
    h[k] = v
  end
  h
end

#auto(&block) ⇒ Object Also known as: automatic

Converts enumerable object into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason #auto examines the enumerable being converted and then dispatches the conversion to the most suitable specialized function. There are three possibilities for this.

If the enumerable is a collection of perfect pairs, like that which Hash#to_a generates, then conversion is handled by #flat.

a = [ [:a,1], [:b,2] ]
a.hashify.auto  #=> { :a=>1, :b=>2 }

If it contains only arrays, but are not perfect pairs, then #multi is called.

a = [ [:a,1,2], [:b,2], [:c], [:d] ]
a.hashify.auto  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If it contains objects other then arrays then the #splat method is called.

a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
a.hashify.auto  #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }

Be aware this is not as efficient as using the underlying methods directly because it must perform an initial iteration over the enumerable to determine its contents.


183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/core/facets/enumerable/hashify.rb', line 183

def auto(&block)
  pairs, mixed = true, false

  each do |e|
    case e
    when Array
      pairs = false if e.size > 2
    else
      mixed = true
    end
  end

  if mixed
    splat(&block)
  elsif pairs
    flat(&block)
  else
    multi(&block)
  end
end

#by_indexObject

Convert enumerable object to Hash using index as keys.

[:a, :b, :c].hashify.by_index  #=> {1=>:a, 2=>:b, 3=>:c}

146
147
148
149
150
151
152
# File 'lib/core/facets/enumerable/hashify.rb', line 146

def by_index
  h = {}
  each_with_index do |v, i|
    h[i] = v
  end
  h
end

#concatObject Also known as: multi

When a mixed or multi-element associative array is used, the result is as follows:

a = [ [:a,1,2], [:b,2], [:c], :d ]
a.hashify.concat  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the first entry of the subelements is the same, then the values will be merged using #concat.

a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
a.hashify.concat  #=> { :a=>[1,2,3,4] }

130
131
132
133
134
135
136
137
# File 'lib/core/facets/enumerable/hashify.rb', line 130

def concat
  h = {}
  each do |k,*v|
    h[k] ||= []
    h[k].concat(v)
  end
  h
end

#each(&b) ⇒ Object (private)


210
211
212
# File 'lib/core/facets/enumerable/hashify.rb', line 210

def each(&b)
  @enum.each(&b)
end

#each_with_index(&b) ⇒ Object (private)


215
216
217
# File 'lib/core/facets/enumerable/hashify.rb', line 215

def each_with_index(&b)
  @enum.each_with_index(&b)
end

#flatObject

This is equivalent to Hash, but it will pad the array with a nil object if there are not an even number of elements.

a = [:a,1,[:b,2,:c]]
a.to_h_flat  #=> { :a=>1, :b=>2, :c=>nil }

79
80
81
82
83
# File 'lib/core/facets/enumerable/hashify.rb', line 79

def flat
  a = @enum.to_a.flatten
  a << nil if a.size.odd?
  Hash[*a]
end

#mergeObject

Like associate but does force values into an array.


110
111
112
113
114
115
116
# File 'lib/core/facets/enumerable/hashify.rb', line 110

def merge
  h = {}
  each do |k,v|
    h[k] = v
  end
  h
end

#splatObject

This is equivalent to Hash, but it will pad the array with a nil object if there are not an even number of elements.

a = [:a,1,:b,2,:c]
a.to_h_splat  #=> { :a=>1, :b=>2, :c=>nil }

67
68
69
70
71
# File 'lib/core/facets/enumerable/hashify.rb', line 67

def splat
  a = @enum.to_a
  a << nil if a.size.odd?
  Hash[*a]
end