Class: NumericHash
- Inherits:
-
Hash
- Object
- Hash
- NumericHash
- Defined in:
- lib/numeric_hash.rb,
lib/numeric_hash/version.rb
Overview
Defines a hash whose values are Numeric or additional nested NumericHashes.
Common arithmetic methods available on Numeric can be called on NumericHash to affect all values within the NumericHash at once.
Constant Summary collapse
- DEFAULT_INITIAL_VALUE =
Default initial value for hash values when an initial value is unspecified. Integer 0 is used instead of Float 0.0 because it can automatically be converted into a Float when necessary during operations with other Floats.
0
- BINARY_OPERATORS =
[:+, :-, :*, :/, :%, :**, :&, :|, :^, :div, :modulo, :quo, :fdiv, :remainder]
- UNARY_OPERATORS =
[:+@, :-@, :~@, :abs, :ceil, :floor, :round, :truncate]
- VERSION =
"0.1.2"
Class Method Summary collapse
-
.sum(array) ⇒ Object
Sums an array of NumericHashes, taking into account empty arrays.
Instance Method Summary collapse
- #apply_array!(array, initial_value = DEFAULT_INITIAL_VALUE) ⇒ Object
- #apply_hash!(hash, initial_value = DEFAULT_INITIAL_VALUE) ⇒ Object
-
#compress ⇒ Object
Compress the hash to its top level values, totaling all nested values.
- #compress! ⇒ Object
-
#ignore_negatives ⇒ Object
Set all negative values in the hash to zero.
-
#initialize(initial_contents = nil, initial_value = DEFAULT_INITIAL_VALUE) ⇒ NumericHash
constructor
Initialize the NumericHash with an array of initial keys or hash of initial key-value pairs (whose values could also be arrays or hashes).
-
#max ⇒ Object
Returns the key-value pair with the largest compressed value in the hash.
-
#min ⇒ Object
Returns the key-value pair with the smallest compressed value in the hash.
-
#normalize(magnitude = 1.0) ⇒ Object
Normalize the total of all hash values to the specified magnitude.
-
#strip_zero ⇒ Object
Strips out any zero valued asset classes.
- #to_amount(amount) ⇒ Object
- #to_percent ⇒ Object
-
#to_ratio ⇒ Object
Shortcuts to normalize the hash to various totals.
-
#total ⇒ Object
Total all values in the hash.
Constructor Details
#initialize(initial_contents = nil, initial_value = DEFAULT_INITIAL_VALUE) ⇒ NumericHash
Initialize the NumericHash with an array of initial keys or hash of initial key-value pairs (whose values could also be arrays or hashes). An optional initial value for initial keys can be specified as well.
NumericHash.new # => { }
NumericHash.new([:a, :b]) # => { :a => 0, :b => 0 }
NumericHash.new([:c, :d], 1.0) # => { :c => 1.0, :d => 1.0 }
NumericHash.new(:e => 2, :f => 3.0) # => { :e => 2, :f => 3.0 }
NumericHash.new({ :g => 4, :h => [:i, :j] }, 5.0) # => { :g => 4, :h => { :i => 5.0, :j => 5.0 } }
28 29 30 31 32 33 34 |
# File 'lib/numeric_hash.rb', line 28 def initialize(initial_contents = nil, initial_value = DEFAULT_INITIAL_VALUE) case initial_contents when Array then apply_array!(initial_contents, initial_value) when Hash then apply_hash!(initial_contents, initial_value) else raise ArgumentError.new("invalid initial data: #{initial_contents.inspect}") if initial_contents end end |
Class Method Details
.sum(array) ⇒ Object
Sums an array of NumericHashes, taking into account empty arrays.
@array # => [ { :a => 1.0, :b => 2 }, { :a => 3, :c => 4 } ]
sum(@array) # => { :a => 4.0, :b => 2, :c => 4 }
sum([]) # => { }
254 255 256 |
# File 'lib/numeric_hash.rb', line 254 def sum(array) array.empty? ? self.new : array.sum end |
Instance Method Details
#apply_array!(array, initial_value = DEFAULT_INITIAL_VALUE) ⇒ Object
36 37 38 |
# File 'lib/numeric_hash.rb', line 36 def apply_array!(array, initial_value = DEFAULT_INITIAL_VALUE) array.each { |key| self[key] = initial_value } end |
#apply_hash!(hash, initial_value = DEFAULT_INITIAL_VALUE) ⇒ Object
40 41 42 43 44 |
# File 'lib/numeric_hash.rb', line 40 def apply_hash!(hash, initial_value = DEFAULT_INITIAL_VALUE) hash.each do |key, value| self[key] = (value.is_a?(Array) || value.is_a?(Hash)) ? NumericHash.new(value, initial_value) : convert_to_numeric(value) end end |
#compress ⇒ Object
Compress the hash to its top level values, totaling all nested values.
@hash # => { :a => 1, :b => { :c => 2.0, d: => 3 } }
@hash.compress # => { :a => 1, :b => 5.0 }
62 63 64 |
# File 'lib/numeric_hash.rb', line 62 def compress map_values { |value| convert_to_numeric(value) } end |
#compress! ⇒ Object
66 67 68 |
# File 'lib/numeric_hash.rb', line 66 def compress! map_values! { |value| convert_to_numeric(value) } end |
#ignore_negatives ⇒ Object
Set all negative values in the hash to zero.
@hash # => { :a => -0.6, :b => 1.2, :c => 0.4 }
@hash.ignore_negatives # => { :a => 0.0, :b => 1.2, :a => 0.4 }
114 115 116 |
# File 'lib/numeric_hash.rb', line 114 def ignore_negatives convert_negatives_to_zero(self) end |
#max ⇒ Object
Returns the key-value pair with the largest compressed value in the hash.
105 106 107 |
# File 'lib/numeric_hash.rb', line 105 def max compressed_key_values_sorted.last end |
#min ⇒ Object
Returns the key-value pair with the smallest compressed value in the hash.
99 100 101 |
# File 'lib/numeric_hash.rb', line 99 def min compressed_key_values_sorted.first end |
#normalize(magnitude = 1.0) ⇒ Object
Normalize the total of all hash values to the specified magnitude. If no magnitude is specified, the hash is normalized to 1.0.
@hash # => { :a => 1, :b => 2, :c => 3, :d => 4 }
@hash.normalize # => { :a => 0.1, :b => 0.2, :c => 0.3, :d => 0.4 }
@hash.normalize(120) # => { :a => 12.0, :b => 24.0, :c => 36.0, :d => 48.0 }
77 78 79 80 81 |
# File 'lib/numeric_hash.rb', line 77 def normalize(magnitude = 1.0) norm_factor = magnitude / total.to_f norm_factor = 0.0 unless norm_factor.finite? # If total was zero, the normalization factor will not be finite; set it to zero in this case. map_values { |value| value * norm_factor } end |
#strip_zero ⇒ Object
Strips out any zero valued asset classes.
@hash # => {:a => 0.0, :b => 0.0, :c => 0.8, :d => 0.15, :e => 0.05, :f => 0.0, :g => 0.0, :h => 0.0, :i => 0.0}
@hash.strip_zero # => {:c => 0.8, :e => 0.05, :d => 0.15}
123 124 125 126 |
# File 'lib/numeric_hash.rb', line 123 def strip_zero # TODO: Previous version of the code only retained values > 0.0, so the refactored code below retains this behavior; verify whether this is still desired. compress.select_values! { |value| value > 0.0 } end |
#to_amount(amount) ⇒ Object
93 94 95 |
# File 'lib/numeric_hash.rb', line 93 def to_amount(amount) normalize(amount) end |
#to_percent ⇒ Object
89 90 91 |
# File 'lib/numeric_hash.rb', line 89 def to_percent normalize(100.0) end |
#to_ratio ⇒ Object
Shortcuts to normalize the hash to various totals.
85 86 87 |
# File 'lib/numeric_hash.rb', line 85 def to_ratio normalize(1.0) end |
#total ⇒ Object
Total all values in the hash.
@hash1 # => { :a => 1.0, :b => 2 }
@hash2 # => { :c => 3, :d => { :e => 4, :f => 5} }
@hash1.total # => 3.0
@hash2.total # => 12
53 54 55 |
# File 'lib/numeric_hash.rb', line 53 def total values.map { |value| convert_to_numeric(value) }.sum end |