Class: Hash
Overview
Hash extensions
Instance Method Summary collapse
-
#merge_recurse(other_hash) ⇒ Object
Return a new hash containing the contents of other_hash and the contents of hsh.
-
#pivot(direction = 'keys', &block) ⇒ Object
Hash#pivot aggregates values for a hash of hashes, for example to calculate subtotals and groups.
-
#size? ⇒ Boolean
Does the hash contain any items?.
-
#sort_by_keys ⇒ Hash
Sort the hsh items by the keys.
Methods included from Pairable
#each_key!, #each_pair!, #each_sort, #each_value!, #map_key, #map_pair, #map_value, #yield_pair
Instance Method Details
#merge_recurse(other_hash) ⇒ Object
Return a new hash containing the contents of other_hash and the contents of hsh.
If no block is specified, the value for entries with duplicate keys will be that of other_hash; if the values are both hashes, then this method recurses.
Otherwise the value for each duplicate key is determined by calling the block with the key, its value in hsh and its value in other_hash.
@example:
h1 = {a: 'b', c: {d: 'e'}}
h2 = {a: 'B', c: {d: 'E'}}
h1.merge_recurse(h2)
#=> {a: 'B', c: {d: 'E'}}
48 49 50 51 52 53 54 55 56 |
# File 'lib/sixarm_ruby_ramp/hash.rb', line 48 def merge_recurse(other_hash) merge(other_hash){|key, oldval, newval| if oldval.is_a?(Hash) && newval.is_a?(Hash) oldval.merge_recurse(newval) else newval end } end |
#pivot(direction = 'keys', &block) ⇒ Object
Hash#pivot aggregates values for a hash of hashes, for example to calculate subtotals and groups.
Suppose you have data arranged by companies, roles, and headcounts.
data = {
"Apple" => {"Accountants" => 11, "Designers" => 22, "Developers" => 33},
"Goggle" => {"Accountants" => 44, "Designers" => 55, "Developers" => 66},
"Microsoft" => {"Accountants" => 77, "Designers" => 88, "Developers" => 99},
}
To calculate each company’s total headcount, you pivot up, then sum:
data.pivot(:up,&:sum)
=> {
"Apple"=>66,
"Goggle"=>165,
"Microsoft"=>264
}
To calculate each role’s total headcount, you pivot down, then sum:
data.pivot(:down,&:sum)
=> {
"Accountants"=>132,
"Designers"=>165,
"Developers"=>198
}
Generic example:
h={
"a"=>{"x"=>1,"y"=>2,"z"=>3},
"b"=>{"x"=>4,"y"=>5,"z"=>6},
"c"=>{"x"=>7,"y"=>8,"z"=>9},
}
h.pivot(:keys) => {"a"=>[1,2,3],"b"=>[4,5,6],"c"=>[7,8,9]}
h.pivot(:vals) => {"x"=>[1,4,7],"y"=>[2,5,8],"z"=>[3,6,9]}
Calculating subtotals
The pivot method is especially useful for calculating subtotals.
Block customization
You can provide a block that will be called for the pivot items.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/sixarm_ruby_ramp/hash.rb', line 126 def pivot(direction='keys',&block) a=self.class.new direction=direction.to_s up=pivot_direction_up?(direction) each_pair{|k1,v1| v1.each_pair{|k2,v2| k = up ? k1 : k2 a[k]=[] if (a[k]==nil or a[k]=={}) a[k]<<(v2) } } if block a.each_pair{|key,val| a[key]=block.call(val)} end a end |
#size? ⇒ Boolean
Does the hash contain any items?
15 16 17 |
# File 'lib/sixarm_ruby_ramp/hash.rb', line 15 def size? size>0 end |